Writing Aegir Modules
Background
The new Aegir is one MidCOM component that resides in midcom.admin.aegir and that handles all uris below it's topic. The main class is fairly small and all it does is intercepts the requests, decide which module should handle the request, load the module and send it on its way.
It also provides the needed services as styles, navigation and location menus.
To make an Aegir module, you can create a normal MidCOM, but with a few extra classes.
The first twist is that those parts of the Module that you want Aegir to be able to handle should be extensions of midcom_baseclasses_components_handler and not the normal _requests class. This is because Aegir uses the handlers system in baseclasses to route request to different modules.
This should make it possible to write modules that provide one interface in Aegir and another through AIS or on normal midcom pages.
Navigation
Aegir assumes that a module can deliver not only all leafs but also list it's nodes. Therefore you must provide an extra navigation class in the module that provides an interface for getting and listing both nodes and leaves. This class should extend the midcom_admin_aegir_module_navigation class found in the Aegir directory.
The interface is as close to normal MidCOM nav as possible.
One thing you should be avare of is the way the interface signals that it wants the root nodes of an object. This happen by calling list_nodes('0'). Note that 0 is not an int but a char. The reason for this is that it has proven simpler to write reliable checks like if( $root == '0') than trying to check for 0.
Module interface class
To keep the Aegir stuff outside the normal MidCOM api there is a special Aegir interface that is initialized before the request handler is run. You can find this interface in the request_data array.
All Aegir Modules should have the interface class. The main job of the class is to provide the static function get_request_switch() that returns an array over which urls the module can handle.
The fixed args array of the request_swith should start with a unique word that identifies the module, for example:
function get_request_array()
{
$request_switch= Array
(
'fixed_args' =>array('simplecontent', 'article'),
'handler' => array('midcom_admin_simplecontent_article','article'),
'variable_args' => 1,
);
return $request_switch;
}
If you do not do this, you'll end up with having to define more than one module in the Module registry, that is not a good thing.
The module interface also contains a few pointers to other conveniencevariables: (I'm assuming you are inside the handler here)
$this->_request_switch'aegir_interface'->current will give you the key of the current module in the module registry. $this->_request_switch'aegir_interface'->registry gives you a pointer to the module registry. $this->_request_switch'aegir_interface'->module_config gives you a pointer to a midcom_helper_configuration that reads the local module configuration sources.
Styles
At the moment, all styleelements must reside in the Aegir modules style directory or you have to use include() to get them from the local style directory. This is not a satisfactory situation, but it will be solved.
The module registry.
The module registry is where Aegir checks which component should get the honours of handling a request. As is usual with MidCOM, the registry is a simple array that will be evaled.
The format is:
registry => Array (
=> array(
'component' => ,
'name' =>
// hide or show the module in navigation:
'hide' => boolean ,
'icon' => ,
'description' => ,
['permissions' => array (
'' =>
)
)
)
Let's have a look at an example:
'registry' => array (
'simplecontent' => array (
'component' => 'midcom.admin.simplecontent',
'name' => 'Topics and Articles',
'description' => '',
'hide' => false
),
'rcs' => array (
'component' => 'no.bergfald.rcs',
'name' => 'Version control',
'hide' => true,
),
)
What this says is that the navigation menu should only show the topics and articles item, but if Aegir gets a uri like /aegir/rcs/something, it should check with the rcs component to see if it is willing to handle the request.
Thus you can have generalized components that work across other modules to provide special services (in this case rcs).
Toolbars and location menu
As some of you probably know, there is a midcom_helper_toolbars class that provides a static class that is an interface to different toolbars. I plan go get the class used in AIS soon as well so that we use the same method across the board.
The class is accessed like this:
$this->_toolbars = &midcom_helper_toolbars::get_instance(); /* add item to the bottom toolbar */ $this->_toolbars->bottom->add_item($item)
For now the toolbar has the following pointers: * bottom - the lower toolbar on the top * top - the top toolbar * aegir_location - the aegir location menu (also implemented as a toolbar). * aegir_menu - the top menu of Aegir.
