Table of Contents

  1. Introduction
  2. Menus
    1. Top Menu
      1. left
      2. mid left
    2. Side Menu
  3. Calling procedure at entering the application
  4. Permissions
  5. Backenddriver
  6. Content-Page
    1. Layout
      1. Templates
      2. Horde_Forms
    2. Scripts
  7. Services
  8. Misc


by Torben Dannhauer

The process of populating the new module with content/functionality is fairly straight forward and after learning how the Horde API' s work, you should be able to produce new modules in a minimum amount of time.
Jan Schneider talked about this at FOSDEM 2005. You can find his slides at

The new module's functionality could by separated in the following aspects:

Usually it is useful to analyse another hordemodule to learn how this work. I analysed Kronolith and it helped me a lot.

Obviously it is necessary to know the provided horde API zu write a horde module. Because a beginner (and this tutorial is adressed to them) has no clue about it, it is very usefull to read the package-documentation at


In Horde there are two standard menus: The top menu an the side menu.

ToDo: Add links to Wikipages describing menus in detail.

Top Menu

The top menu is devided in to 4 sections:


the menuitmes this module intentionally provide are located in the file <module>/lib/Module.php in the function ::getMenu()

Add Items like this:

 $menu->add(Horde::applicationUrl('pagetoshow.php'), _("MenuItemName"), 'icon.png', $registry->getImageDir() );

mid left

Items are added in <module>/config/menu.php:

$_menu[] = array(
      'url' =>        '',
      'text' =>       'Example, Inc.',
      'icon' =>       'example.png',
      'icon_path' =>  '',
      'target' =>     '_blank',
      'onclick' =>    ''

Side Menu

1. In the horde config/registry.d/<module>.php you added for your module, add sidebar entries:

$this->applications['<module>-menu'] = array(
    'status' => 'sidebar',
    'sidebar_params' => array(
        'id' => 'menu',
    'app' => '<module>',
    'menu_parent' => '<module>',

2. Then copy and paste the sidebarCreate() function from, e.g. kronolith/lib/Application.php, into <module>/lib/Application.php.
3. Edit it to do what you want. The id in your sidebar_params above will match the $params['id'] that gets passed in.

Calling procedure at entering the application

If a module is entered via the side-menu, usualy the url to the module-folder was provided. The link ist http://<myHordeInstallation>/<mymodule> without any file suffix. So the calling procedure starts by executing the index.php on the webserver.



The module's permissiontree which includes the logical structure of all permissions available in this module is defined in <module>/lib/api.php

Further information about permissions is available at


The easiest way to learn writing a backend-Driver for managing the data your first module works with is to extend the Skeletons SQL-Driver.

<configstring name="table2" desc="My Database">mymodule_table which is needed</configstring>


The basic procedure to create Content-Pages is:

It is a good point to start a contentpage by copying the Skeleton's list.php

All viewable pages ar located in the module's root-folder. All businesslogic (classes etc,) are located in separate files in <module>/lib.


Creating the Page-Layout consists of two main tasks:
1. Creating forms for data manipulation
1. and - if the page is complex enought (nearly every page is it) you can store the html-content in templates.

If a submenu on the content page ist needed (like in turba), it can be generated via <div class="control nowrap"></div>


WARNING: The Horde_Template package is no longer supported. You should use (( instead.

To move your businesslogic-variabes to a html-layout, the Horde_Templates-Package is usefull. You can include templates with code tags, and Horde will replace these tags with your variable content, if the tags and the variables are associated via template->setVariable(...);. For further information read about this package use : /Doc/Dev/TemplatePackageH32


// Prepare Variables
$title = 'myFormtitle';
$vars = Variables::getDefaultVariables();

// Prepare Form
$form = &new Horde_Form($vars, $title, 'accountstatement_Form');
$renderer = new Horde_Form_Renderer();

// Add form fields & Variables.
$form->addHidden('', 'example_hidden', 'int', false);
$form->addVariable(_("Title"), 'title', 'text', false);

// ---------------------- Render Form ------------
// Writes the HTML <form....> opening tag.
$form->open( $renderer,  $vars,  'accountstatement.php', 'post');    

// Titelzeile rendern

/* writes the via addVariable(...) and addHidden(...) added inputtypes.
 Available types are: */
$renderer->renderFormActive($form, $vars);

// writes the "submit" input button

// writes the HTML </form> tag

// stop renderer

If you want to manipulate form variables in javascript, you must set any value to that variable, otherwise it is not initialized correctly. If you plan to use a form for hidden values only, you will see a thin line in HTML. To prevent that, you can add a variable with type 'spacer'. This type has no visible content and the thin line caused by the "only hidden values" disappears.

To read or write the form variables user $vars->set( $variablename, $value); and $myVar = $vars->get( $variablename, $defaultvalue_if_not_available ); .


If any scripts are needed for layout like striped.js für alternating rowcolors, add these scripts via Horde::addScriptFile('<script.js', 'ownerapplication_where_to_search: e.g. horde', true ). True means that the script should be included with a relativ path.