\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
\part{Introduction}
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.<br />
Jan Schneider talked about this at FOSDEM 2005. You can find his slides at <a href="http://www.horde.org/papers/fosdem2005/">http://www.horde.org/papers/fosdem2005/</a>.

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

\begin{itemize}
\item Menus


\item Calling-procedure at entering the application


\item Permissions


\item All Content-Pages which are accessible through on oh the menus


\item Services offered to external modules


\end{itemize}
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 <a href="http://dev.horde.org/api/framework/">http://dev.horde.org/api/framework/</a>.

\part{Menus}
In Horde there are two standard menus: The top menu an the side menu.

<a href="https://wiki.horde.org/ToDo">ToDo</a>: Add links to Wikipages describing menus in detail.

\section{Top Menu}
The top menu is devided in to 4 sections:

\begin{itemize}
\item left: menuitems provided by this module: see below


\item mid left: menuitems added manually: see below


\item mid right: menuitems added in the administrator's module setup


\item right: menuitems provided by horde as default


\end{itemize}
\subsection{left}
the menuitmes this module intentionally provide are located in the file <module>/lib/Module.php in the function ::getMenu()

Add Items like this:

<pre><code class="language-php"> 
 \$menu->add(Horde::applicationUrl('pagetoshow.php'), \_("MenuItemName"), 'icon.png', \$registry->getImageDir() );
</code></pre>
\subsection{mid left}
Items are added in <module>/config/menu.php:

<pre><code class="language-php">
\$\_menu[] = array(
      'url' =>        'http://www.example.com/',
      'text' =>       'Example, Inc.',
      'icon' =>       'example.png',
      'icon\_path' =>  'http://www.example.com/images/',
      'target' =>     '\_blank',
      'onclick' =>    ''
  );
</code></pre>
\section{Side Menu}
\begin{itemize}
\item In the horde config/registry.d/<module>.php you added for your module, add sidebar entries:


\end{itemize}
<pre><code>
\$this->applications['<module>-menu'] = array(
    'status' => 'sidebar',
    'sidebar\_params' => array(
        'id' => 'menu',
    ),
    'app' => '<module>',
    'menu\_parent' => '<module>',
);
</code></pre>
\begin{itemize}
\item Then copy and paste the sidebarCreate() function from, e.g. kronolith/lib/Application.php, into <module>/lib/Application.php.


\item Edit it to do what you want. The id in your sidebar\_params above will match the \$params['id'] that gets passed in.


\end{itemize}
\part{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 <a href="http://\">http://\textbackslash\{\}</a><myHordeInstallation>/<mymodule> without any file suffix. So the calling procedure starts by executing the index.php on the webserver.

Procedure:

\begin{itemize}
\item Executing index.php: initialzing, load configfiles and load the page which should be displayed at the beginning (e.g. in Skeleton: list.php).


\item list.php calls >module>/lib/base.php to initialize the module and then proceeds with its content.


\item now lists.php is displayed. By Clicking on any menuitem another contentpage as list.php (but of course also list.php again) could be displayed (->executed).


\end{itemize}
\part{Permissions}
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 <a href="http://wiki.horde.org/Doc/Dev/[PermsPackage](PermsPackage)">http://wiki.horde.org/Doc/Dev/[PermsPackage](PermsPackage)</a>

\part{Backenddriver}
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.

\begin{itemize}
\item Edit config/conf.xml: Add the databset tables you want be configurable. Attention: one databaset table with name "table" MUST exist! Example :


\end{itemize}
<pre><code>
<configstring name="table2" desc="My Database">mymodule\_table which is needed</configstring>
</code></pre>
\begin{itemize}
\item go to your horde configuration, configurate your module to get your conf.php written with your new configs.


\item ...to proceed


\end{itemize}
\part{Content-Page}
The basic procedure to create Content-Pages is:

\begin{itemize}
\item create .inc files that display the elements on the screen


\item create any php files needed to fill in forms


\end{itemize}
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.

\section{Layout}
Creating the Page-Layout consists of two main tasks:

\begin{itemize}
\item Creating forms for data manipulation


\item and - if the page is complex enought (nearly every page is it) you can store the html-content in templates.


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

\subsection{Templates}
\textbf{WARNING: The Horde\_Template package is no longer supported. You should use <a href="http://wiki.horde.org/Doc/Dev/Horde_View">http://wiki.horde.org/Doc/Dev/Horde\_View</a> 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 wiki.horde.org : /Doc/Dev/<a href="https://wiki.horde.org/TemplatePackageH32">TemplatePackageH32</a>

\subsection{Horde\_Forms}
<pre><code class="language-php">
// 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
\$renderer->beginActive(\$title);

/* writes the via addVariable(...) and addHidden(...) added inputtypes.
 Available types are: http://wiki.horde.org/Doc/Dev/FormTypes?referrer=Doc\%2FDev\%2FFormPackage\# */
\$renderer->renderFormActive(\$form, \$vars);

// writes the "submit" input button
\$renderer->submit();

// writes the HTML </form> tag
\$form->close(\$renderer);

// stop renderer
\$renderer->end();
</code></pre>
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 ); .

\section{Scripts}
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.

\part{Services}
\part{Misc}
\end{document}
