community.egroupware.org: Community wiki

  
Community wiki
Sitemgr Module developer manual

back to ManualSitemgr

SiteMgr's parent module class, defines all the important functionality a module needs in its lifetime. Thus creating a new module can be as easy as creating a class that extends the standard module, defines the module's arguments if there are any, and has a function get_content that produces the module's content. Let's start with “Hello World”.

<?php
class module_hello extends Module
{
function module_hello()
{
$this->arguments = array(
'name' => array(
'type' => 'textfield',
'label' => 'The person to say hello to'
)
);
$this->title = "Hello world";
$this->description = "This is a simple sample module";
}
function get_content($arguments,$properties)
{
return lang('Hello') . ' ' . $arguments['name'];

}

}

Once your module is registered (Modules must be stored in the directory /path/to/eGroupWare/sitemgr/modules and be named class.module_modulename.inc.php in order that sitemgr can find them.) and added to the list of permitted modules for some context, users can create blocks from this module: They will see in the content manager a textfield where they edit the argument name, and once the block is activated, it will generate the hello phrase on the website. Easy, isn't it?

Now let's examine more in detail how the standard module is constructed. This will help you understand in what way you can extend it to create more powerful modules. It defines the following functions:

add_transformer($transformer)

This function adds a transformer class to the module's transformer chain, so that when a block is generated from this module, its content will be passed through $transformer. This function is automatically called for block transformers, but you can use it on your own, if you want to separate in your module raw content from different forms of output. There is only one function a transformer class has to provide:

apply_transform($title,$content)

A transformer that is not a block transformer should normally ignore the title argument, and construct its return value from the content argument.

set_block(&$block,$produce=False)

This function is called by the content manager (with $produce=False) and by the page generation (with $produce=True) for each content block, so that the module knows everything about the block it has to edit or generate (above all its context and its arguments). If your module overrides this function, it should always call the parent class' set_block function first with parent::set_block($block,$produce). If you want to configure your module with respect to the block, you can do this here. This is also the place where your module should add the transformers it needs for generating output. For example:

function set_block(&$block,$produce=False)
{
parent::set_block($block,$produce)
if ($produce)
{
$this->add_transformer(new my_transform());

}

}
get_properties()

This function looks up the value of the module's properties for the context of a block. There should not be much reason to override this function.

get_user_interface()

This function is responsible for creating the interface you use in the content manager when you edit a module's arguments. If you want this interface to show more than your module's arguments, youcan override this function. It must return an array of interface elements where each element is an array with two values associated to the keys label and form. You can even dynamically construct arguments, sitemgr's sample gallery module shows how to do this.

get_admin_interface($defaults)

This function creates the interface for editing module properties, it works in a similar way to get_user_interface.

get_translation_interface($fromblock,$toblock)

This function creates the interface for the translation manager. If your module makes use of sitemgr multilingual feature, and you have overriden get_user_interface, you'll probably have to override this function too.

build_input_element(($input,$default,$elementname)

This is a helper function for above functions. If you override one of above functions you can use build_input_element in the same way as the parent module does.

validate(&$data)

This function is called when a module's arguments are edited. The parent class simply returns true. When you override this function, you can alter the arguments, a reference to which is passed to the function, but you can also return false, and set the module's validation_error variable. In this case, the arguments will not be saved and the validation error is displayed to the user. For example we could add the following lines to our hello module:

function validate(&$data) 
{
if (preg_match("/[[:upper:]]/",$data['name']))
{
$data['name'] = strtolower($data['name']);
$this->validation_error = "Name has been translated to lower case";
}

return true;

}

This would make sure that the module argument name would always be lowercase.

get_content(&$arguments,$properties)

This is the function every module needs. It produces the module's content. It is passed two arrays, one with the arguments for the block the module is generating, and the other with the properties that apply for the block's context. At the moment there is no constraint on what type of date the get_content function returns. It can be html, xml, an array, etc. But if it does not return html, you have to provide a transformer capable to produce html from the data get_content produces. The arguments are passed as a reference, because the get_content function can change them, and they can get stored automatically as session variable. This is because the parent module provides one other service: Your module can rely on an automatic handling of HTTP GET, POST and COOKIE variables, and of session variables. All you'd have to do is to define the arrays $this->get, $this->post, $this->cookie and $this->session. All members of these variables will be fetched from the GET, POST or COOKIE parameters, or from session variables and stored for you in the $arguments array. The entries of $this->session additionnaly will be stored after get_content returns to get_output. This can be very useful if you want your module to remain in a stable state while the user interacts with other modules on the same page.

The variables you define in these arrays can be identical to those in $this->arguments. In this case, if they are defined in the HTTP session context, they will override the values the page contributor has defined for the page. But they can be different variables that do not need an initial value provided by the page contributor. Whereas $this->get,$this->cookie and $this->session are simple arrays enumerating the variable names, $this->post is special because it can contain the element definition in the same way as $this->arguments, which can be used to programatically construct the form elements.

Your module does not need to use this service, it could directly read HTTP variables. The advantage of using it is that it provides a namespace for each module, so that if different modules that use the same variable names are used on the same page, no problems occur. If you use this service you can construct URLS automatically with the modules link function (see below), and if you construct the user interface, you have to provide the correct form element names for this service to work. The build_post_element function can help you do this. For example lets extend our hello module, so that the site user can choose his own name. Since we can no longer rely on the validation that is automatically done on contributor provided input. we call validate from the get_content function.

<?php
class module_hello extends Module {
function module_hello()
{
$this->arguments = array(
'name' => array(
'type' => 'textfield',
'label' => 'The person to say hello to'
)
);
$this->post = array('name' => array('type' => 'textfield'));
$this->session = array('name');
$this->title = "Hello world";
$this->description = "This is a simple sample module";
}
function get_content(&$arguments,$properties)
{
$this->validate($arguments);
return lang('Hello') . ' ' . $arguments['name'] . '<br><form action="' .
$_SERVER['REQUEST_URI'] . '" method="post">' .
$this->build_post_element('name',lang('Enter a name') .
'</form>';
}
function validate(&$data)
{
if (preg_match("/[[:upper:]]/",$data['name']))
{
$data['name'] = strtolower($data['name']);
$this->validation_error = "Name has been translated to lower case"; }
return true;

}

}
build_post_element($key,$default=False)

You can use this function from your module's get_content function to construct form elements. This works with the argument definition you put into $this->post. If you do not provide a default the current blocks value for the argument will be filled in.

link($modulevars)

helps you construct URLS with GET parameters that use the service described above. modulevars is an array of variable values keyed on variable names.

find_template_dir()

if a module uses a different template (of whatever kind) for different site themes, this function can help finding the template directory inside the theme's directory, if it follows the namespace described above, or if it cannot be found name the default directory.

get_output($type='html')

This is the function that is actually called by the page generation engine, since it not only calls the module's get_content function, but makes sure that all transformers that have been added to the modules transformer_chain get called. For type argument is not really used at the moment, but future versions of sitemgr could be extended so that modules could produce output in different formats by specifying different transformers for each output type. Your module should not need to override get_output.

To summarize, there are the following requirements for a sitemgr module:

  1. It is written as a class called module_name and extends the class Module. It must be put into a file called class.module_name.inc.php and put into the inc directory of any eGroupWare application.

  2. Its constructor should define the following member variables:

    1. arguments: the module's arguments a contributor can edit in order to create content blocks from the module. Each argument needs to define a label and the type of input element used to edit it in the content manager. Parameters for these input elements (like size for textfields, cols and rows for textareas can be defined). Translatable arguments can be specially flagged with a i18n entry in the arguments definition array (If a module wants to make use of sitemgr's translation feature, it must additionally set the module member variable i18n to true.).

    2. properties: the module's properties the site administrator can edit in order to constrain or configure the functionnality of the module

    3. title: The module's default title that can be overriden for each content block.

    4. description: A short descriptive text, that is displayed in the content manager and module manager (for example when you put the mouse over an entry in the module select lists).

  3. It needs a get_content function that has access to arguments and properties and produces the block content.

  4. If the content returned by get_content is something different from HTML, the module has to define transformer classes, and should add them to the module's transformer chain. This can be done in the constructor, but the best place for it is the set_block function

  5. The parent module class provides a user interface for editing module arguments. If a module needs a customized interface or wants to construct arguments dynamically, it can override the get_user_interface function.

These are the building blocks which should allow for some flexibility in constructing modules that make eGroupWare managed data visible on a sitemgr web site.



You are here