PFSenseDevWiki : CoreGUI2Introduction

PfSenseDevHome :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register
Most recent edit on 2007-08-18 23:35:04 by ChrisBuechler

Additions:

A rough, incomplete and inaccurate introduction to CoreGUI2



Deletions:

A rough, incomplete and innacurate introduction to CoreGUI2





Oldest known version of this page was edited on 2007-08-18 23:34:47 by ChrisBuechler []
Page view:

A rough, incomplete and innacurate introduction to CoreGUI2


Overview


A CoreGUI2 interface is composed by at least 2 XML documents:

- The master document contains information about tabs and other "global" stuff.
- The interface document contains the description of the interface.

The master documents begin with the <coregui_master> tag, and the interface documents begin with <coregui_interface>. Master documents should include a <version> tag. Although versioning is not implemented yet, it might be useful in the future. It's recommended that you include it, and specify version 2 (so it becomes <version>2</version>).

The master document


A master document must indicate at least one interface document. Each interface document is specified in <tab> tags (because they're displayed as top tabs, and that should also be familiar to pkg_edit.php devs). There isn't a limitation on the maximum number of tabs allowed per cg2 master, but it's probably not a good idea to have more than 6 or 7 interfaces, since our current themes doesn't scale too well.

Instead of specifying the interface documents in XML using the <tab> tag, you can use the <tab_function> tag to specify a function that should return the exact same fields that would be returned when parsing <tab> tags (as a PHP array, of course). As of now this isn't implemented yet, but it's a 5-minute (or even less) job, so if you need it done, drop me a note and I'll add it to cg2.

The <tab> tag is composed by the following <tags>:


In the future, the <url> tag might be implemented so that cg2 tabs can link to non-cg2 interfaces (another trivial task).

You can also specify PHP includes that will be included (in fact, require_once'd) when the cg2 page is loaded by using the <include> tag, and you can include javascript and CSS into your cg2 pages by using the <include_javascript> and <include_css> tags, respectively.

The interface document


The interface document is far more complex. You can also use <include>, <include_css> and <include_javascript> here. A cg2 interface is composed by <element> tags, and those are composed by <widget> tags.

The notion of widgets should be pretty much straightforward (it's borrowed from pkg_edit's fields). Each widget represents a button, a select, or something like that. It's similar to real GUI programming (Qt, Gtk, Winforms, etc.) in some aspects.

You must also define a <config_key> for your interface (it's how you're gonna identify it). If you don't specify a <config_key>, the settings in your interface won't be saved to config.xml. This is particularly good for cg2 pages that only display information or allow you to define some parameters and execute a database query, showing the results afterwards, for example.

Elements


An element holds widgets. The way the widgets are displayed depends on the type of the element. Currently, there are 3 types of elements: form, table and step. A form is pretty much what pkg_edit.php was - it simply displays the widgets, nothing fancy about it. A table displays configuration options that can be added, removed, moved around, edited, etc. (think Firewall -> Rules). Finally, the step type is just like the form type, except that it contains next, previous, cancel and finish buttons. That allows you to construct wizards.

If your <element> is of the <table> type, you can define the <buttons> tag. For example, you might want to use only an add button and a delete button. So use <buttons>add,edit</buttons>. So far only 4 button types are defined: add, edit, delete, move. More buttons can be added on demand, and a "custom" button type should be implemented in the future.

Widgets


Every <widget> tag must also specify a <type>, which is an identifier for the type of the widget (for example, "select", "button", "port", "subnet"). Check cg2_widgets.inc for a list of possible widget types.

Some widgets require more than the type specification. In fact, so far there isn't a single widget that is fully functional without other properties set. This document would be too long if we tried to explain the specs for each widget. Right now, there's no documentation for that (we should start documenting cg2_widgets.inc with something like Doxygen), but cg2_widgets.inc is fairly simple.

Although all widgets are free to require any property they want, most of them share similar properties. Here is a list of the most commonly used properties:


Some widgets also make use of the <caption> tag. The CheckboxWidget uses it to display some information next to the checkbox (it's good for supplying information that is more complete than what's supplied in the label tag, but less complete than what's supplied in the description property). The Button widget and its descendants use it to set the string that's written on the button.

Widgets that allow choice generally receive their options from <option> tags. Those tags can appear multiple times in the same widget, and should contain the tags <label> and <name>, where <label> is the text that should be selected so that the value of the widget becomes <name>.

Most fields can display a default value if the page has not been saved to config.xml yet. Those use the property <value>. Widgets should be aware whether they are getting their value from default values set by the interface developer or if they are using values retrieved from config.xml, and adapt their look accordinagly.

Special widgets


There's a special widget type named "custom". It allows you to create your own widgets (generally by inheriting from cg2_widgets.inc's Widget class) and specify their class in the <class> tag.

For tables, you can also use the <not_in_table/> property. Widgets marked with that tag won't show up in tables, only in forms and wizards.

There's also the value_merger field. It merges the value of two or more wizards using either AND (<merge_and>foo_field,bar_field</merge_and>) or OR (<merge_or>foo_field,bar_field</merge_or>). It's only used in tables.

TextboxWidgets accept two special options: <validation_regex> and <validation_message>. When validating textbox widgets, if <validation_regex> is set, the widget will be validated against the regex specified (using Perl regular expressions). If it doesn't validate, the string specified in <validation_message> will be displayed as an input error.

Utility functions and callbacks


CoreGUI2 is callback-oriented. Instead of defining PHP snippets that are eval'ed when there's an event, you should use function names that will be called when those events occur. Note that most (or maybe all events) occur within the context of <element> tags.

The most useful event is probably <on_apply_event>. It's triggered when your settings are applied. In cg2 interfaces, you generally save the interface (by clicking any Submit button on a cg2 form) and then you apply the settings by clicking the "Apply settings" button. On apply events, you should resync your configuration to config files, restart services, etc..

In order to resync your config, you must obtain information on how the interface fields were set. To do that, you generally use get_element_config($key) where $key is the <config_key> of the interface. If your interface has more than one element, use get_element_config($key, $element_index). For tables, use get_table_rows($key) or get_table_rows($key, $element_index) to retrieve an array of config arrays (one for each row).

A config array is an array holding $name => $value pairs, just like config.xml. Fields that can contain multiple values might return $value as an array of values.

There are more utility functions, so take a look at cg2_util.inc for more info. See cg2_elements.inc for a list of the current supported events. Then add more information about them here in this wiki, if possible.

Final observations


Do not ever try to use $_POST directly! $_POST should only be used by internal cg2 stuff. The names you give to the widgets aren't their real names in the resulting HTML. In fact, widgets might have more than 1 HTML name each, or maybe even no HTML names at all.

Also, never name your widget starting with "cg2_" and never name your Javascript functions starting with "_ _" (FIXME: no space between those underscores, need formatting help) or cg2_. Those are reserved for cg2's internal stuff.

Future plans



This document


This document is a rough introduction to the cg2 system. It's incomplete, and might contain many grammar/spelling mistakes and blatant omissions. It might also be innacurate. Feel free to expand or correct it (and expand or correct cg2 as well).

Many things are still not documented. Volunteers needed.
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.3
Page was generated in 0.0800 seconds