phpgroupware-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Phpgroupware-cvs] CVS: sitemgr/doc makedoc.sh,NONE,1.1 modules.dvi,NON


From: Michael Totschnig <address@hidden>
Subject: [Phpgroupware-cvs] CVS: sitemgr/doc makedoc.sh,NONE,1.1 modules.dvi,NONE,1.1 modules.html,NONE,1.1 modules.lyx,NONE,1.1 modules.pdf,NONE,1.1 modules.ps,NONE,1.1 modules.sgml,NONE,1.1 modules.txt,NONE,1.1
Date: Thu, 16 Jan 2003 22:37:54 -0500

Update of /cvsroot/phpgroupware/sitemgr/doc
In directory subversions:/tmp/cvs-serv24731/doc

Added Files:
        makedoc.sh modules.dvi modules.html modules.lyx modules.pdf 
        modules.ps modules.sgml modules.txt 
Log Message:
First commit of a new modularized architecture for sitemgr 


--- NEW FILE ---
# this scripts helps make the documentation in html ps and pds
# the sed scripts is there to counter a bug in docbook export of Lyx
set -x
mv modules.sgml modules.sgml.bak
sed "s/<\/listitem><\/listitem>/<\/listitem>/" modules.sgml.bak >modules.sgml
db2html -u modules.sgml
mv modules/modules.html .
rm -rf modules
db2dvi modules.sgml
dvips -o modules.ps modules.dvi
ps2pdf modules.ps

--- NEW FILE ---
÷ƒ’À;




Õn‘0



╍‘0
 popŽ“ïcolor push  Black.ï    color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push  Black.ï       color 
popŽ“ïcolor push  Black.ï       color popŽ“ïcolor push gray 0ïhtml:<a 
href="#139">8ï  html:</a>ï      color popŽŸõ¾ïcolor push gray 0ïhtml:<a 
href="#154">Ÿp¨‘0


ÙM‘0



Üҍ‘0



Ptype“as“those“that“can“be“harÑðdcoded.“This“is“mostly“useful“for“modules“likeŽ¡‘H
Üҍ‘0
#raw“content“a“module“prÑðoduces“and“the“way“it“should“get“displayed“on“the“webŽ¡‘0
Üҍ‘0
ÙM‘0
àinterface“for“crÑðeating“content“blocks“is“the“same“on“each“level“of“scope,“besidesŽ¡‘0
ÈøT‘ÿs8itleŽ¡ïhtml:<a name="90">ï     html:</a>ŸÈø‘0

Üҍ‘0
7ïhtml:<a name="158">ï        html:</a>Ÿ      ¯^‘0


7ïhtml:<a name="182">ï        html:</a>Ÿ
Èøget_user_interface()Ž¦ïhtml:<a name="183">ï html:</a>¡‘0

ršÑðeturns“trëˆue.“When“you“override“this“function,“you“can“alter“the“ar˜gu-Ž¡‘D
 b>


ÌÌ{Ž¡‘Y™˜function‘ffmodule_hello()Ž¡‘Y™˜{Ž¡‘o30$this->name–ff=“"hello";Ž¡‘o30$this->arguments–ff=“array(Ž¡’

7ïhtml:<a name="215">ï        html:</a>Ÿ
Èølink($modulevars)ŽŸPïhtml:<a name="216">ï html:</a>Ÿ
簍‘0
















 b>


--- NEW FILE ---
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>Introduction to sitemgr modules</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"></HEAD
><BODY
CLASS="ARTICLE"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="ARTICLE"
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
><A
NAME="AEN2">Introduction to sitemgr modules</H1
><DIV
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="50%"
CELLSPACING="0"
CELLPADDING="0"
ALIGN="CENTER"
><TR
><TD
VALIGN="TOP"
><B
>Abstract</B
></TD
></TR
><TR
><TD
VALIGN="TOP"
><P
>This text provides an overview of sitemgr's proposed new modularized 
>architecture and contains the information users, administrators, template 
>designers and application devellopers need in order to get started using 
>sitemgr as a flexible web site managment system that can easily make any 
>information and business logic phpgroupware knows about publicly accessible. 
>This text also serves as a request for comments, so that sitemgr's new 
>generation can be adapted quickly to the needs of PHPgroupware's user 
>community. Please be aware that at the moment the new sitemgr is still 
>experimental and that there are some areas of its functionnality that need 
>further developpment.</P
></TD
></TR
></TABLE
></DIV
><HR
WIDTH="75%"
ALIGN="CENTER"
COLOR="#000000"
SIZE="1"></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="#AEN10"
>Introduction</A
></DT
><DT
><A
HREF="#AEN77"
>User manual</A
></DT
><DT
><A
HREF="#AEN106"
>Administrator manual<A
NAME="ADMINISTRATOR-MANUAL"
></A
></A
></DT
><DT
><A
HREF="#AEN140"
>Template designer manual<A
NAME="TEMPLATE-DESIGNER-MANUAL"
></A
></A
></DT
><DT
><A
HREF="#AEN155"
>Application developper manual<A
NAME="APPLICATION-DEVELOPPER-MANUAL"
></A
></A
></DT
></DL
></DIV
><DIV
CLASS="SECT1"
><H2
CLASS="SECT1"
><A
NAME="AEN10">Introduction</H2
><P
>For the next generaton of phpgroupware's web site managment application 
>sitemgr, we propose a new page generation architecture whose fundamental idea 
>is that all dynamic web site content is built by modules. In this section, I 
>will sketch a short outline of how this architecture works and I will present 
>the concepts it makes use of.</P
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN13">Template</H3
><P
>Sitemgr builds web sites from templates. Those are stored in the directory 
>sitemgr/sitemg-site/templates. Each of them has a directory of its own. The 
>file main.tpl defines the template of the whole site, there can be other files 
>that define code for separate areas of the page or for specific modules. 
>Templates contain four kinds of variables. These are explained here since the 
>types 2,3 and 4 can be used both in the template as in the page content a 
>module generates.</P
><P
></P
><OL
TYPE="1"
><LI
><P
>{contentarea: areaname} These define where administrator and contributor 
>provided content go. The names and the number of contentareas a template 
>defines are almost arbitrary.</P
></LI
><LI
><P
>{appname.modulename(?arguments)}These let you hardcode a call to a module into 
>a template. Arguments are in the HTTP GET query string syntax 
>(?key1=value1&#38;key2=value2). At the moment, if you use this type of 
>variables, you have to urlencode the query string yourself. Future versions of 
>sitemgr might provide a simpler notation. For example,{sitemgr.lang_block] 
>creates the select box for multilingual sites.</P
></LI
><LI
><P
>{?(phpgw|sitemgr:)link} This lets you create links either to other pages of 
>your website, or to phpgroupware applications:</P
><P
></P
><OL
TYPE="a"
><LI
><P
>Links to sitemgr either start with '?sitemgr:' or only with '?'. You can 
>either link to a page with {?page_name=downloads] and [?page_id=4}, to a 
>category's index (?category_id=5), to the site index (?index), to the site's 
>table of contents (?toc). Just [?] or {?sitemgr:} links to the administrator 
>defined home page.</P
></LI
><LI
><P
>Links to phpgw start with '?phpgw:' . You have to name the application 
>followed by a comma, and optionnally arguments the application can interpret. 
>For example {?phpgw:/addressbook,order=n_given&#38;sort=ASC}.</P
></LI
></OL
></LI
><LI
><P
>{variable} Finally there are some simple variables you can use to retrieve 
>metainformation about the page or about the user's context:</P
><P
></P
><OL
TYPE="a"
><LI
><P
>{title} the page title</P
></LI
><LI
><P
>{subtitle} the page subtitle</P
></LI
><LI
><P
>{sitename}the sitename the administrator has chosen for the site</P
></LI
><LI
><P
>{footer}the administrator edited footer</P
></LI
><LI
><P
>{header}the administrator edited header</P
></LI
><LI
><P
>{user}the user's account name</P
></LI
></OL
></LI
></OL
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN43">Module</H3
><P
>The main function of a sitemgr module is to generate dynamic web site content. 
>To make the development of new modules, and the use of modules easy and 
>convenient, sitemgr defines an &#8220;abstract&#8221; class module which each 
>module should extend. This parent of all modules, provides one essential 
>service: It hooks the module into the content managment interface and permits 
>the editing of the module's arguments that determine what content will be 
>generated. Thus in order to create a new module, all you have to do, is to 
>extend the abstract super module, define the modules arguments, and write a 
>get_content function that returns the content that should be displayed on the 
>website. More on this in chapter<A
HREF="#APPLICATION-DEVELOPPER-MANUAL"
>5</A
>.</P
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN47">Argument/Content</H3
><P
>A module can be seen as a transformation of input arguments into generated 
>content. It is important to understand that the input arguments can be of 
>completely different kinds. On the one hand there can be arguments that are as 
>close as possible to the generated content. For example the html module's only 
>argument is named &#8220;htmlcontent&#8221; and in normal circumstances it is 
>not transformed at all but handed over as is to the page generation engine. On 
>the other hand arguments can play any conceivable role in the generation of 
>content that is driven by data coming from other phpgroupware applications. 
>They can be used to select between different categories of content, they can 
>choose a certain format of presentation, they can function as search terms, 
>etc.</P
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN50">Properties</H3
><P
>A module can define properties. Properties are accessible to the modules 
>get_content function in the same way as arguments, but they differ from them 
>in two ways:</P
><P
></P
><UL
><LI
><P
>Properties are edited by the site administrator. Their intended role is to put 
>certain constrains on the workings of the module, so that a site administrator 
>can enforce certain rules. For example the standard html module defines a 
>property called striphtml. If this boolean property is set the module replaces 
>all html in the generated content with entities.</P
></LI
><LI
><P
>Properties are not defined with respect to a certain generated content block, 
>but are defined either on a site-wide level or on the level of specific 
>categories. Additionally you can differenciate on each scope properties for 
>each content area. When a content block is generated, properties are searched 
>for in a cascading way, i.e. when the block is specific to a specific page and 
>contentarea and the module's properties are not defined for the combination of 
>the contentarea and the page's category, then properties defined for higher 
>scopes are looked for in a certain order. More on this in chapter<A
HREF="#ADMINISTRATOR-MANUAL"
>3</A
>.</P
></LI
></UL
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN59">Blocks, content areas and scope</H3
><P
>There are three ways a module can generate content that will be displayed on a 
>web page:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>A template can contain hardcoded calls to modules that will generate content 
>visible on each page. Thus you could put dynamic content that is visible 
>across the whole site on a place of its own directly into the template. But 
>beware that restrictions defined by the administrator also apply to these 
>hardcoded module calls.</P
></LI
><LI
><P
>A template defines several content areas. This is one important differenced 
>between the modularized sitemgr and previous versions where there were was 
>only one place where contributor edited content went (page_content) and two 
>places for administrator configured blocks (right_blocks, left_blocks). Now 
>templates can define any practical number of content areas with arbitrary 
>names. And there is no more much difference between central and peripheric 
>areas. All can show administrator and contributor provided block content.With 
>one exeption: The name &#8220;center&#8221; is special in that special pages 
>that get generated by special URLs like &#8220;?toc&#8221; and 
>&#8220;?index&#8221; or &#8220;?category_id=number&#8221; always put there 
>page content (which is internally generated by nothing else than a module) 
>into this content area. If your template does not have a content area called 
>&#8220;center&#8221; these special URLs won't work.
Content areas can display module output, as edited by the page's contributors. 
We refer to each output of a module as a block. Here is another important 
difference to how sitemgr used to work: Until now there was a sharp distinction 
between page content which replaces the template variable page_content, and 
side blocks which got defined in a special file called blockconfig and replaced 
the template varialbes right_blocks and left_blocks. Now from the perspective 
of the page generation engine there is no more any difference between content 
areas, all display blocks of content generated by modules.
The blocks one content area displays can be defined on different levels of 
scope: There are site wide blocks that are visible across the whole site, 
category wide blocks, that are visible on pages that belong to the category or 
any of its children, and finally are page blocks that define what distinguishes 
the page from other pages, and normally will be that what you'd call the page's 
main content.</P
></LI
><LI
><P
>The block content generated by a module can contain template variables of the 
>same type as those that can be hardcoded. This is mostly useful for modules 
>like the html module, where the contributor specified argument is nearly 
>identical to the generated content. Thus a contributor can embed module calls 
>inside the content of a certain block. This is done only once without any 
>recursion, i.e. if a embedded module call returns itself a template variable 
>it is not parsed and processed again.</P
></LI
></OL
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN69">Transformer</H3
><P
>The architecture for sitemgr modules provides for the distinction between some 
>form of raw content a module produces and the way it should get displayed on 
>the web site, with the future possibility to plug other display types into the 
>same framework. The idea is that the raw content of a module gets passed 
>through different transformers, possibly even several transformers in a 
>sequence at the time of content generation. Additionally this provides for a 
>use of modules outside of sitemgr, for example remote retrieval of information 
>with something like XML-RPC. </P
><P
>At the moment, a module does not need to use transformers on its own, it can 
>directly generate html content, but if it does, sitemgr provides for an easy 
>way to chain different transformers together. Thus a module can be constructed 
>in different layers of functionality. For example a module's get_content 
>function could return data inXML, and it defines a XSLT transformation to 
>reorganize this data, and a second transformer for creating a user interface 
>for display.</P
><P
>Transformers are also used on the level of the site template, insofar as each 
>contentarea can have an associated transformer, which wraps the different 
>content blocks into a common display format. This does the same thing as the 
>file sideblock.tpl in former versions of sitemgr.</P
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN74">Translations</H3
><P
>Sitemgr in its new modularized architecture continues to be fully 
>multilingual. It is very simple to have a new module use this feature. All 
>that is needed is to use a special flag in the definition of the module's 
>arguments. All arguments that have this flag will be stored in a language 
>specific database table, and can be translated in the translation manager, 
>very similar to the way category and page definitions could already be 
>translated to several languages.</P
></DIV
></DIV
><DIV
CLASS="SECT1"
><HR><H2
CLASS="SECT1"
><A
NAME="AEN77">User manual</H2
><P
>The most important difference for site contributors between the modularized 
>sitemgr and its older versions is that in the page manager now there are two 
>different interfaces for each page:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>When you create a new page or when you click on the Edit button which is 
>associated with an existing page, you no longer edit the page content, but 
>only some basic metainformation about the page as its name, title, subtitle 
>and sort order, and you can change the category the page belongs to.</P
></LI
><LI
><P
>There is a new interface that gets displayed when you click on a page's 
>&#8220;Manage content&#8221; button. It is here that you create the content 
>blocks for each page.</P
></LI
></OL
><P
>The second difference is that now a contributor can also define content blocks 
>for the whole category he has write access for. These category wide blocks 
>will be seen on each page that belongs to the category or to any of its 
>subcategories. There are also side wide content blocks that only the site 
>administrator can create.</P
><P
>The interface for creating content blocks is the same on each level of scope, 
>besides that when editing blocks on a lower level you can see all the blocks 
>that have been defined on a higher level, and will be displayed on the website 
>together with the blocks you are editing. I will refer to this interface as 
>the content manager.</P
><P
>In each content manager, there is a section for each content area, where you 
>can add blocks selected from a menu of all available modules. Once you have 
>added a new block, it appears amidst all other blocks of the content area. 
>Those defined on higher level scopes are only displayed, those pertaining to 
>the scope (site-wide, category or page) you are managing are editable. There 
>are four standard interface elements you can edit for each block:</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>Title</DT
><DD
><P
>Each module defines a default title for blocks it generates. The block title 
>is not necessarily displayed in each content area. It depends on the block 
>transformer defined for the content area by the site template you use. Here 
>you can override the default title with a customized title that will only be 
>used by the block you are editing.</P
></DD
><DT
>Actif</DT
><DD
><P
>When you create a new block, it is not immediately visible on the web site. 
>This makes sense since you need to edit its arguments first. When you are 
>finished defining a blocks arguments, you have to check the actif flag to make 
>it visible. This can also be practical if you want to hide some content 
>temporarily from the web site without deleting it from the database.</P
></DD
><DT
>Seenby</DT
><DD
><P
>You can control the visibility of each block for the different user roles 
>defined by sitemgr: site administrators, phpgroupware users (which include 
>site administrators) and the anonymous user. Evidently you can also make the 
>block visible for everyone which is the default. </P
></DD
><DT
>Sortorder</DT
><DD
><P
>Here you can change the order in which the blocks are displayed by defining a 
>different integer for each block.</P
></DD
></DL
></DIV
><P
>After these, you have to edit the module specific arguments, each of which is 
>preceded by an explanatory label. The input elements for arguments can be of 
>different types: checkboxes, selectboxes, textareas, textfields. In the case 
>of text input, you can use the same template variables as are used in the site 
>template. But be aware that this only works if the module puts the same 
>variable into its output, which need not necessarily be the case.</P
></DIV
><DIV
CLASS="SECT1"
><HR><H2
CLASS="SECT1"
><A
NAME="AEN106">Administrator manual<A
NAME="ADMINISTRATOR-MANUAL"
></A
></H2
><DIV
CLASS="SECT2"
><H3
CLASS="SECT2"
><A
NAME="AEN109">Installation</H3
><P
></P
><OL
TYPE="1"
><LI
><P
>Once you have the sitemgr directory inside your phpgroupware install you can 
>setup it like any other phpgroupware application with the setup program 
>(http://yourmachine/phpgw-path/setup/). You should also install the 
>sitemgr-link application, which is is inside sitemgr and has to be moved up in 
>the directory hierarchy.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>cd sitemgr
mv sitemgr-link ..</PRE
></TD
></TR
></TABLE
><P
>and then install sitemgr-link with setup</P
></LI
><LI
><P
>Log in to phpGroupWare as an admin and create an anonymous phpgw user and 
>assign it a password. The only app (I assume) that they should have access to 
>is sitemgr-link. sitemgr-link is a dummy application that redirects phpGW 
>users to the generated site.</P
></LI
><LI
><P
>Users who you wish to see sitemgr (aka contributors) must be given acces to 
>sitemgr, users who you want to be able to link to the sitemgr site from phpGW 
>must be given rights to sitemgr-link. The easiest way to do this is to go to 
>User groups and give groups permissions to use the applications. </P
></LI
><LI
><P
>The sitemgr-site is the directory that serves the dynamic web site. It is 
>located inside sitemgr and works without moving it somewhere else. But it can 
>be located anywhere. For example, you could put it in /var/www/html. You could 
>make the root location of your web server point to it, if you wish (ie, 
>http://yourmachine/ refers to /var/www/html/sitemgr-site if you moved the 
>directory, or to /path/to/phpgroupware/sitemgr/sitemgr-site if you did not). 
>Make a mental note of the directory where you put it and the url that it is 
>accessed by.</P
></LI
><LI
><P
>In the sitemgr-site directory is a file called config.inc.php. You only have 
>to edit it if you moved the directory. Change the value of the line</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>'phpgw_path'           =&#62; '../../',</PRE
></TD
></TR
></TABLE
><P
>so that the value of $sitemgr_info['phpgw_path'] is '/path/to/phpgroupware/'</P
></LI
><LI
><P
>You're almost set to go. Log in to phpGroupWare as an adminis trator. Make 
>sure you gave yourself the sitemgr and sitemgr-link applications so that you 
>see them on your navbar. Go to the sitemgr application and select "Configure 
>SiteMgr". Fill in &#8220;URL to sitemgr-site&#8221; and &#8220;Filesystem path 
>to sitemgr-site directory&#8221;, and the anonymous user's name and password. 
>Then click on save, and you should know select the template for your site.</P
></LI
><LI
><P
>That's it. Go to the Category manager, add a category or three and check who 
>can view and edit them, then go to the page manager, add a page or three to 
>each category, set up your site header, site footer, etc., and go view your 
>recently created site by clicking on the sitemgr-link application. Voilà!</P
></LI
></OL
></DIV
><DIV
CLASS="SECT2"
><HR><H3
CLASS="SECT2"
><A
NAME="AEN130">Maintenance</H3
><P
>As a site administrator, you have three privileges/responsibilies:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>Define site wide content blocks. These are edited in the same interface as 
>category and page specific blocks.</P
></LI
><LI
><P
>Choose permitted modules: If you choose &#8220;Manage site-wide module 
>properties&#8221; from sitemgr's main menu, you will see several rows which 
>all contain four elements: a select box, a button labelled &#8220;Select 
>allowed modules', another select box and a button labelled &#8220;Configure 
>module properties&#8221;. The first select box and its adjacent button in each 
>row permits to choose lists of permitted modules. The first row defines a 
>master list for the whole site which is used when no more specific lists are 
>found for content areas or categories. The following rows each pertain to the 
>different content areas of your site template. Here you can choose to allow 
>some modules for one content areas, and other modules for another one.
In the category manager, there is a button &#8220;Manage Modules&#8221; 
associated with each category. There you can use the same interface to define 
lists specific to one category (and all its subcategories, unless overriden). 
Again you have the choice between one list that pertains to all content areas, 
and specific lists for each category.
When sitemgr has to find a specific value of permitted lists in a given context 
(a given contentarea in a given category) the following algorithm is used: 
First it aks for a value defined for the pair contentarea/category. If none is 
defined, it climbs up the category hierarchy until the site wide value, each 
time looking for a value defined for the pair contentarea/category. If none can 
be found, it returns to the given category the search started from, and now 
asks for values defined for the given category but independent from the 
contentarea. If there is still none defined, it repeats the same traversal up 
the category hierarchy. This means that by simply defining one global master 
list of permitted modules, you can configure the whole site, if you do not need 
more fine grained control.
The lists of permitted lists are never merged, if you define one list for a 
given context, this list is used in this context.</P
></LI
><LI
><P
>Define module properties: The lookup algorithm for module properties is 
>exactly the same as for the lists of permitted modules. For each module you 
>can set properties for the whole site, for content areas, for categories, or 
>for combinations of content areas and categories. You access the property 
>editor from the same page where you choose the list of permitted modules. You 
>just use the second select box in each row. By selecting one module and 
>clicking the &#8220;Configure module properties&#8221; button, you will open a 
>interface for editing the module's properties which ressembles the interface 
>for editing module arguments in the content manager. Be aware that only some 
>modules define properties.</P
></LI
></OL
></DIV
></DIV
><DIV
CLASS="SECT1"
><HR><H2
CLASS="SECT1"
><A
NAME="AEN140">Template designer manual<A
NAME="TEMPLATE-DESIGNER-MANUAL"
></A
></H2
><P
>One main idea behind sitemgr's modularized architecture is that all dynamic 
>content on the website is produced by a module. This permits for a very 
>structural way of defining functionality and for an easy way of extending 
>functionality. With respect to former versions of sitemgr, this means that the 
>templates have to be slightly modified:</P
><P
></P
><UL
><LI
><P
>The whole page template is now stored in a file main.tpl in the template's 
>directory.</P
></LI
><LI
><P
>The variables page_content, left_blocks,right_blocks have to be replaced by 
>content areas: {contentarea:center}, {contentarea:left}, {contentarea:right}. 
>Only the contentarea center has a special semantics, since it is the hardcoded 
>value for the display of table of contents and side index. All other 
>contentareas can have arbitrary names, and you can have any practical number 
>of them.</P
></LI
><LI
><P
>A contentarea serves to display the content blocks, the site administrator and 
>contributors define. Each contentarea can have its own way of wrapping html 
>code around each content block. This at the moment defined in a class that 
>implements the transformer interface, i.e. defines a function 
>apply_transform($title,$content).This class' name is areaname_bt (for 
>blocktransformer) and it is stored in file areaname_bt.inc.php inside the 
>template directory. The function apply_transform just has to wrap the desired 
>html around the content. It is free to ignore the title, for example the block 
>title does not necessarily make sense in a page's central content area. A 
>block transformer could apply other transformations to the content, but this 
>would probably have counter-intuitive effects on your page's contributors.</P
></LI
><LI
><P
>Other than that a template directory can contain template files that are 
>specific to a certain module. For example the news module uses a file 
>newsblock.tpl which is a standard API template. It is up to a module's 
>developpers what kind of templates he wants to use. We propose to use a 
>namespace for these module specific template files. For example a template 
>used by module 'news_admin.news' would go into a subdirectory 
>'news_admin/news' in each template directory. If the module does not find a 
>template it needs in the site template's directory, it should look for a 
>default template file, for example in &#8220;default/news_admin/news'.</P
></LI
><LI
><P
>You can hardcode module calls into the template if your site should have the 
>same dynamic content on one specific place.</P
></LI
></UL
></DIV
><DIV
CLASS="SECT1"
><HR><H2
CLASS="SECT1"
><A
NAME="AEN155">Application developper manual<A
NAME="APPLICATION-DEVELOPPER-MANUAL"
></A
></H2
><P
>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 &#8220;Hello World&#8221;.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?php
class module_hello extends Module 
{      
    function module_hello()  
    {               
        $this-&#62;arguments = array(
            'name' =&#62; array(
                'type' =&#62; 'textfield', 
                'label' =&#62; 'The person to say hello to'
            )
        );
        $this-&#62;title = "Hello world";
        $this-&#62;description = "This is a simple sample module";   
    }
    function get_content($arguments,$properties)    
    {
        return lang('Hello') . ' ' . $arguments['name'];
    }
}</PRE
></TD
></TR
></TABLE
><P
>Once your module is registered 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?</P
><P
>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:</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>add_transformer($transformer)</DT
><DD
><P
>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:</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>apply_transform($title,$content)</DT
><DD
><P
>A transformer that is not a block transformer should normally ignore the title 
>argument, and construct its return value from the content argument.</P
></DD
></DL
></DIV
></DD
><DT
>set_block($block,$produce=False)</DT
><DD
><P
>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). 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:</P
></DD
></DL
></DIV
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>function set_block($block) 
{ 
    parent::set_block($block);
    if ($produce)
    {
        $this-&#62;add_transformer(new my_transform());
    }
}</PRE
></TD
></TR
></TABLE
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>get_properties()</DT
><DD
><P
>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.</P
></DD
><DT
>get_user_interface()</DT
><DD
><P
>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.</P
></DD
><DT
>get_admin_interface($defaults)</DT
><DD
><P
>This function creates the interface for editing module properties, it works in 
>a similar way to get_user_interface.</P
></DD
><DT
>get_translation_interface($fromblock,$toblock)</DT
><DD
><P
>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.</P
></DD
><DT
>build_input_element(($input,$default,$elementname)</DT
><DD
><P
>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.</P
></DD
><DT
>validate(&#38;$data)</DT
><DD
><P
>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:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>function validate(&#38;$data) 
{ 
    if (preg_match("/[[:upper:]]/",$data['name']))
    {
        $data['name'] = strtolower($data['name']);
        $this-&#62;validation_error = "Name has been translated to lower case";
    }
    return true;
}</PRE
></TD
></TR
></TABLE
><P
>This would make sure that the module argument name would always be 
>lowercase.</P
></DD
><DT
>get_content(&#38;$arguments,$properties)</DT
><DD
><P
>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-&#62;get, $this-&#62;post, 
>$this-&#62;cookie and $this-&#62;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-&#62;session 
>additionnaly will be stored after get_content returns to get_output. This can 
>be very useful if you want your module do remain in a stable state while the 
>user interacts with other modules on the same page.</P
><P
>The variables you define in these arrays can be identical to those in 
>$this-&#62;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-&#62;get,$this-&#62;cookie and $this-&#62;session are simple arrays 
>enumerating the variable names, $this-&#62;post is special because it can 
>contain the element definition in the same way as $this-&#62;arguments, which 
>can be used to programatically construct the form elements.</P
><P
>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 you use different modules on the same page, that use the 
>same variable names, you would not run into problems. 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.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?php
class module_hello extends Module  {
    function module_hello()
    {
        $this-&#62;name = "hello";
        $this-&#62;arguments = array(
            'name' =&#62; array(
                'type' =&#62; 'textfield',
                 'label' =&#62; 'The person to say hello to'
            )
        );
       $this-&#62;post = array('name' =&#62; array('type' =&#62; 'textfield'));
       $this-&#62;session = array('name');
       $this-&#62;title = "Hello world";
       $this-&#62;description = "This is a simple sample module";
    }
    function get_content(&#38;$arguments,$properties)
    {
       $this-&#62;validate($arguments);
       return lang('Hello') . ' ' . $arguments['name'] . '&#60;br&#62;&#60;form 
action="' .
           $_SERVER['REQUEST_URI'] . '" method="post"&#62;' .
               $this-&#62;build_post_element('name',lang('Enter a name') .
           '&#60;/form&#62;';
    }
    function validate(&#38;$data)
    {
       if (preg_match("/[[:upper:]]/",$data['name']))
       {
           $data['name'] = strtolower($data['name']);
           $this-&#62;validation_error = "Name has been translated to lower 
case";                }
       return true;
   }
}</PRE
></TD
></TR
></TABLE
></DD
><DT
>build_post_element($key,$default=False)</DT
><DD
><P
>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-&#62;post. If you do not provide a default the current blocks value for 
>the argument will be filled in.</P
></DD
><DT
>link($modulevars)</DT
><DD
><P
>helps you construct URLS with GET parameters that use the service described 
>above. modulevars is an array of variable values keyed on variable names.</P
></DD
><DT
>get_output($type='html')</DT
><DD
><P
>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.</P
></DD
></DL
></DIV
><P
>To summarize, there are the following requirements for a sitemgr module:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>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 phpgroupware application.</P
></LI
><LI
><P
>Its constructor should define the following member variables:</P
><P
></P
><OL
TYPE="a"
><LI
><P
>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.</P
></LI
><LI
><P
>properties: the module's properties the site administrator can edit in order 
>to constrain or configure the functionnality of the module</P
></LI
><LI
><P
>title: The module's default title that can be overriden for each content 
>block.</P
></LI
><LI
><P
>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).</P
></LI
></OL
></LI
><LI
><P
>It needs a get_content function that has access to arguments and properties 
>ans produces the block content.</P
></LI
><LI
><P
>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</P
></LI
><LI
><P
>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.</P
></LI
></OL
><P
>These are the building blocks which should allow for some flexibility in 
>constructing modules that make phpgroupware managed data visible on a sitemgr 
>web site.</P
></DIV
></DIV
></BODY
></HTML
>
--- NEW FILE ---
#LyX 1.2 created this file. For more info see http://www.lyx.org/
\lyxformat 220
\textclass docbook
\begin_preamble
<!entity header system "header.sgml">
\end_preamble
\language english
\inputencoding default
\fontscheme default
\graphics dvips
\paperfontsize default
\spacing single 
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\use_natbib 0
\use_numerical_citations 0
\paperorientation portrait
[...1170 lines suppressed...]
It needs a get_content function that has access to arguments and properties
 ans produces the block content.
\layout Enumerate

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
\layout Enumerate

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.
\layout Standard

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

--- NEW FILE ---
%PDF-1.2
%Ç쏢
6 0 obj
<</Length 7 0 R/Filter /FlateDecode>>
stream
xœíZÛnÛF}蛾BoMz³÷Ëc[h
$ú”LËlx‘EÊNúõ½Ì’’;-‚4‚      ?ÞËìì™3g†&)aKêÒïM³¸[¼~'—Û~q·da
mšåÏ+˜tK¦      •Ò.W7‹¸-™å0¶4Ôŗ«fñê÷vØÿ°úkÁŒP«V׋WÝõa3T]ëg
lÑN§™¡ócÌ%µJc}5”Í6˜ÑœÀ¸M
Ø©ËÞO¼~ÇàxA¸¦Ü{tÅà§ùòŠ‹à,address@hidden>Ï¹uxáòîl‰vV¦Ñ]¸­#VpmЃûê:^V0Â,Cg‹
:„šgA÷ê†qFœÔDÌ5ñÍoo· Ÿ&pĉ)2Š³¯a?qÉàù`Új·`ŽLS$¢jÁ.T³        
ªojÈù2‘AJ͎Á©4#xÉ;8•}”`^ý8e'<
endobj
7 0 obj
1624
endobj
18 0 obj
<</R4
4 0 R>>
endobj
19 0 obj
<</R14
[...983 lines suppressed...]
0000044293 00000 n 
0000044314 00000 n 
0000049162 00000 n 
0000044377 00000 n 
0000047079 00000 n 
0000047100 00000 n 
0000049306 00000 n 
0000047143 00000 n 
0000047373 00000 n 
0000047393 00000 n 
0000063583 00000 n 
0000067863 00000 n 
0000071906 00000 n 
0000072527 00000 n 
trailer
<< /Size 91 /Root 1 0 R /Info 2 0 R
>>
startxref
83856
%%EOF

--- NEW FILE ---
%!PS-Adobe-2.0
%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software
%%Title: modules.dvi
%%Pages: 14
%%PageOrder: Ascend
%%BoundingBox: 0 0 612 792
%%DocumentFonts: Helvetica-Bold Palatino-Roman Palatino-Bold
%%+ Palatino-Italic Courier
%%EndComments
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -o modules.ps modules.dvi
%DVIPSParameters: dpi=600, compressed
%DVIPSSource:  TeX output 2003.01.16:1709
%%BeginProcSet: texc.pro
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
[...1401 lines suppressed...]
(in)g(the)h(constr)o(uctor)-6 b(,)23 b(but)g(the)h(best)f(place)f(for)h
(it)795 2522 y(is)e(the)g(set_block)g(function)p Black
712 2654 a(5.)p Black 20 w(The)33 b(par)o(ent)g(module)h(class)f(pr)o
(ovides)g(a)g(user)h(interface)e(for)h(editing)h(module)g(ar)o(gu-)795
2746 y(ments.)c(If)g(a)f(module)i(needs)e(a)h(customized)g(interface)f
(or)h(wants)g(to)g(constr)o(uct)h(ar)o(gu-)795 2837 y(ments)21
b(dynamically)-9 b(,)21 b(it)f(can)h(override)f(the)h
(get_user_interface)d(function.)596 2970 y(These)h(ar)o(e)f(the)i
(building)h(blocks)f(which)g(should)h(allow)f(for)f(some)i
(\003exibility)f(in)g(constr)o(ucting)596 3061 y(modules)h(that)g(make)
f(phpgr)o(oupwar)o(e)f(managed)i(data)e(visible)i(on)h(a)e(sitemgr)h
(web)g(site.)p Black 3601 5585 a Fd(13)p Black eop
%%Page: 14 14
14 13 bop Black 0 TeXcolorgray Black 197 -132 a Fd(Intr)o(oduction)19
b(to)h(sitemgr)h(modules)p Black Black 197 5585 a(14)p
Black eop
%%Trailer
end
userdict /end-hook known{end-hook}if
%%EOF

--- NEW FILE ---
<!DOCTYPE article  PUBLIC "-//OASIS//DTD DocBook V4.1//EN"
 [ <!entity header system "header.sgml">
 ]>

<article lang="en"><!-- DocBook file was created by LyX 1.2
  See http://www.lyx.org/ for more information -->
<articleinfo><title>Introduction to sitemgr modules</title><date>January 1, 
2003</date><author><firstname>Michael</firstname> 
<surname>Totschnig</surname></author><abstract><para>This text provides an 
overview of sitemgr's proposed new modularized architecture and contains the 
information users, administrators, template designers and application 
devellopers need in order to get started using sitemgr as a flexible web site 
managment system that can easily make any information and business logic 
phpgroupware knows about publicly accessible. This text also serves as a 
request for comments, so that sitemgr's new generation can be adapted quickly 
to the needs of PHPgroupware's user community. Please be aware that at the 
moment the new sitemgr is still experimental and that there are some areas of 
its functionnality that need further 
developpment.</para></abstract></articleinfo>
<sect1><title>Introduction</title><para>For the next generaton of 
phpgroupware's web site managment application sitemgr, we propose a new page 
generation architecture whose fundamental idea is that all dynamic web site 
content is built by modules. In this section, I will sketch a short outline of 
how this architecture works and I will present the concepts it makes use 
of.</para><sect2><title>Template</title><para>Sitemgr builds web sites from 
templates. Those are stored in the directory sitemgr/sitemg-site/templates. 
Each of them has a directory of its own. The file main.tpl defines the template 
of the whole site, there can be other files that define code for separate areas 
of the page or for specific modules. Templates contain four kinds of variables. 
These are explained here since the types 2,3 and 4 can be used both in the 
template as in the page content a module 
generates.</para><orderedlist><listitem><para>&lcub;contentarea: areaname&rcub; 
These define where administrator and contributor provided content go. The names 
and the number of contentareas a template defines are almost 
arbitrary.</para></listitem><listitem><para>&lcub;appname.modulename(?arguments)&rcub;These
 let you hardcode a call to a module into a template. Arguments are in the HTTP 
GET query string syntax (?key1=value1&amp;key2=value2). At the moment, if you 
use this type of variables, you have to urlencode the query string yourself. 
Future versions of sitemgr might provide a simpler notation. For 
example,&lcub;sitemgr.lang_block&rsqb; creates the select box for multilingual 
sites.</para></listitem><listitem><para>&lcub;?(phpgw|sitemgr:)link&rcub; This 
lets you create links either to other pages of your website, or to phpgroupware 
applications:</para><orderedlist><listitem><para>Links to sitemgr either start 
with '?sitemgr:' or only with '?'. You can either link to a page with 
&lcub;?page_name=downloads&rsqb; and &lsqb;?page_id=4&rcub;, to a category's 
index (?category_id=5), to the site index (?index), to the site's table of 
contents (?toc). Just &lsqb;?&rsqb; or &lcub;?sitemgr:&rcub; links to the 
administrator defined home page.</para></listitem><listitem><para>Links to 
phpgw start with '?phpgw:' . You have to name the application followed by a 
comma, and optionnally arguments the application can interpret. For example 
&lcub;?phpgw:/addressbook,order=n_given&amp;sort=ASC&rcub;.</para></listitem></orderedlist></listitem><listitem><para>&lcub;variable&rcub;
 Finally there are some simple variables you can use to retrieve 
metainformation about the page or about the user's 
context:</para><orderedlist><listitem><para>&lcub;title&rcub; the page 
title</para></listitem><listitem><para>&lcub;subtitle&rcub; the page 
subtitle</para></listitem><listitem><para>&lcub;sitename&rcub;the sitename the 
administrator has chosen for the 
site</para></listitem><listitem><para>&lcub;footer&rcub;the administrator 
edited footer</para></listitem><listitem><para>&lcub;header&rcub;the 
administrator edited 
header</para></listitem><listitem><para>&lcub;user&rcub;the user's account 
name</para></listitem></orderedlist></listitem></orderedlist></sect2>
<sect2><title>Module</title><para>The main function of a sitemgr module is to 
generate dynamic web site content. To make the development of new modules, and 
the use of modules easy and convenient, sitemgr defines an 
&ldquo;abstract&rdquo; class module which each module should extend. This 
parent of all modules, provides one essential service: It hooks the module into 
the content managment interface and permits the editing of the module's 
arguments that determine what content will be generated. Thus in order to 
create a new module, all you have to do, is to extend the abstract super 
module, define the modules arguments, and write a get_content function that 
returns the content that should be displayed on the website. More on this in 
chapter<link linkend="Application-developper-manual">5</link>.</para></sect2>
<sect2><title>Argument/Content</title><para>A module can be seen as a 
transformation of input arguments into generated content. It is important to 
understand that the input arguments can be of completely different kinds. On 
the one hand there can be arguments that are as close as possible to the 
generated content. For example the html module's only argument is named 
&ldquo;htmlcontent&rdquo; and in normal circumstances it is not transformed at 
all but handed over as is to the page generation engine. On the other hand 
arguments can play any conceivable role in the generation of content that is 
driven by data coming from other phpgroupware applications. They can be used to 
select between different categories of content, they can choose a certain 
format of presentation, they can function as search terms, etc.</para></sect2>
<sect2><title>Properties</title><para>A module can define properties. 
Properties are accessible to the modules get_content function in the same way 
as arguments, but they differ from them in two 
ways:</para><itemizedlist><listitem><para>Properties are edited by the site 
administrator. Their intended role is to put certain constrains on the workings 
of the module, so that a site administrator can enforce certain rules. For 
example the standard html module defines a property called striphtml. If this 
boolean property is set the module replaces all html in the generated content 
with entities.</para></listitem><listitem><para>Properties are not defined with 
respect to a certain generated content block, but are defined either on a 
site-wide level or on the level of specific categories. Additionally you can 
differenciate on each scope properties for each content area. When a content 
block is generated, properties are searched for in a cascading way, i.e. when 
the block is specific to a specific page and contentarea and the module's 
properties are not defined for the combination of the contentarea and the 
page's category, then properties defined for higher scopes are looked for in a 
certain order. More on this in chapter<link 
linkend="Administrator-manual">3</link>.</para></listitem></itemizedlist></sect2>
<sect2><title>Blocks, content areas and scope</title><para>There are three ways 
a module can generate content that will be displayed on a web 
page:</para><orderedlist><listitem><para>A template can contain hardcoded calls 
to modules that will generate content visible on each page. Thus you could put 
dynamic content that is visible across the whole site on a place of its own 
directly into the template. But beware that restrictions defined by the 
administrator also apply to these hardcoded module 
calls.</para></listitem><listitem><para>A template defines several content 
areas. This is one important differenced between the modularized sitemgr and 
previous versions where there were was only one place where contributor edited 
content went (page_content) and two places for administrator configured blocks 
(right_blocks, left_blocks). Now templates can define any practical number of 
content areas with arbitrary names. And there is no more much difference 
between central and peripheric areas. All can show administrator and 
contributor provided block content.With one exeption: The name 
&ldquo;center&rdquo; is special in that special pages that get generated by 
special URLs like &ldquo;?toc&rdquo; and &ldquo;?index&rdquo; or 
&ldquo;?category_id=number&rdquo; always put there page content (which is 
internally generated by nothing else than a module) into this content area. If 
your template does not have a content area called &ldquo;center&rdquo; these 
special URLs won't work.
Content areas can display module output, as edited by the page's contributors. 
We refer to each output of a module as a block. Here is another important 
difference to how sitemgr used to work: Until now there was a sharp distinction 
between page content which replaces the template variable page_content, and 
side blocks which got defined in a special file called blockconfig and replaced 
the template varialbes right_blocks and left_blocks. Now from the perspective 
of the page generation engine there is no more any difference between content 
areas, all display blocks of content generated by modules.
The blocks one content area displays can be defined on different levels of 
scope: There are site wide blocks that are visible across the whole site, 
category wide blocks, that are visible on pages that belong to the category or 
any of its children, and finally are page blocks that define what distinguishes 
the page from other pages, and normally will be that what you'd call the page's 
main content.</para></listitem><listitem><para>The block content generated by a 
module can contain template variables of the same type as those that can be 
hardcoded. This is mostly useful for modules like the html module, where the 
contributor specified argument is nearly identical to the generated content. 
Thus a contributor can embed module calls inside the content of a certain 
block. This is done only once without any recursion, i.e. if a embedded module 
call returns itself a template variable it is not parsed and processed 
again.</para></listitem></orderedlist></sect2>
<sect2><title>Transformer</title><para>The architecture for sitemgr modules 
provides for the distinction between some form of raw content a module produces 
and the way it should get displayed on the web site, with the future 
possibility to plug other display types into the same framework. The idea is 
that the raw content of a module gets passed through different transformers, 
possibly even several transformers in a sequence at the time of content 
generation. Additionally this provides for a use of modules outside of sitemgr, 
for example remote retrieval of information with something like XML-RPC. 
</para><para>At the moment, a module does not need to use transformers on its 
own, it can directly generate html content, but if it does, sitemgr provides 
for an easy way to chain different transformers together. Thus a module can be 
constructed in different layers of functionality. For example a module's 
get_content function could return data inXML, and it defines a XSLT 
transformation to reorganize this data, and a second transformer for creating a 
user interface for display.</para><para>Transformers are also used on the level 
of the site template, insofar as each contentarea can have an associated 
transformer, which wraps the different content blocks into a common display 
format. This does the same thing as the file sideblock.tpl in former versions 
of sitemgr.</para></sect2>
<sect2><title>Translations</title><para>Sitemgr in its new modularized 
architecture continues to be fully multilingual. It is very simple to have a 
new module use this feature. All that is needed is to use a special flag in the 
definition of the module's arguments. All arguments that have this flag will be 
stored in a language specific database table, and can be translated in the 
translation manager, very similar to the way category and page definitions 
could already be translated to several languages.</para></sect2>
</sect1>
<sect1><title>User manual</title><para>The most important difference for site 
contributors between the modularized sitemgr and its older versions is that in 
the page manager now there are two different interfaces for each 
page:</para><orderedlist><listitem><para>When you create a new page or when you 
click on the Edit button which is associated with an existing page, you no 
longer edit the page content, but only some basic metainformation about the 
page as its name, title, subtitle and sort order, and you can change the 
category the page belongs to.</para></listitem><listitem><para>There is a new 
interface that gets displayed when you click on a page's &ldquo;Manage 
content&rdquo; button. It is here that you create the content blocks for each 
page.</para></listitem></orderedlist><para>The second difference is that now a 
contributor can also define content blocks for the whole category he has write 
access for. These category wide blocks will be seen on each page that belongs 
to the category or to any of its subcategories. There are also side wide 
content blocks that only the site administrator can create.</para><para>The 
interface for creating content blocks is the same on each level of scope, 
besides that when editing blocks on a lower level you can see all the blocks 
that have been defined on a higher level, and will be displayed on the website 
together with the blocks you are editing. I will refer to this interface as the 
content manager.</para><para>In each content manager, there is a section for 
each content area, where you can add blocks selected from a menu of all 
available modules. Once you have added a new block, it appears amidst all other 
blocks of the content area. Those defined on higher level scopes are only 
displayed, those pertaining to the scope (site-wide, category or page) you are 
managing are editable. There are four standard interface elements you can edit 
for each block:</para><variablelist><varlistentry><term>Title
</term><listitem><para>Each module defines a default title for blocks it 
generates. The block title is not necessarily displayed in each content area. 
It depends on the block transformer defined for the content area by the site 
template you use. Here you can override the default title with a customized 
title that will only be used by the block you are 
editing.</para></listitem></varlistentry><varlistentry><term>Actif
</term><listitem><para>When you create a new block, it is not immediately 
visible on the web site. This makes sense since you need to edit its arguments 
first. When you are finished defining a blocks arguments, you have to check the 
actif flag to make it visible. This can also be practical if you want to hide 
some content temporarily from the web site without deleting it from the 
database.</para></listitem></varlistentry><varlistentry><term>Seenby
</term><listitem><para>You can control the visibility of each block for the 
different user roles defined by sitemgr: site administrators, phpgroupware 
users (which include site administrators) and the anonymous user. Evidently you 
can also make the block visible for everyone which is the default. 
</para></listitem></varlistentry><varlistentry><term>Sortorder
</term><listitem><para>Here you can change the order in which the blocks are 
displayed by defining a different integer for each 
block.</para></listitem></varlistentry></variablelist><para>After these, you 
have to edit the module specific arguments, each of which is preceded by an 
explanatory label. The input elements for arguments can be of different types: 
checkboxes, selectboxes, textareas, textfields. In the case of text input, you 
can use the same template variables as are used in the site template. But be 
aware that this only works if the module puts the same variable into its 
output, which need not necessarily be the case.</para></sect1>
<sect1><title>Administrator manual<anchor 
id="Administrator-manual"></title><sect2><title>Installation</title><orderedlist><listitem><para>Once
 you have the sitemgr directory inside your phpgroupware install you can setup 
it like any other phpgroupware application with the setup program 
(http://yourmachine/phpgw-path/setup/). You should also install the 
sitemgr-link application, which is is inside sitemgr and has to be moved up in 
the directory hierarchy.</para><programlisting><![CDATA[cd sitemgr
]]><![CDATA[mv sitemgr-link ..
]]></programlisting><para>and then install sitemgr-link with 
setup</para></listitem><listitem><para>Log in to phpGroupWare as an admin and 
create an anonymous phpgw user and assign it a password. The only app (I 
assume) that they should have access to is sitemgr-link. sitemgr-link is a 
dummy application that redirects phpGW users to the generated 
site.</para></listitem><listitem><para>Users who you wish to see sitemgr (aka 
contributors) must be given acces to sitemgr, users who you want to be able to 
link to the sitemgr site from phpGW must be given rights to sitemgr-link. The 
easiest way to do this is to go to User groups and give groups permissions to 
use the applications. </para></listitem><listitem><para>The sitemgr-site is the 
directory that serves the dynamic web site. It is located inside sitemgr and 
works without moving it somewhere else. But it can be located anywhere. For 
example, you could put it in /var/www/html. You could make the root location of 
your web server point to it, if you wish (ie, http://yourmachine/ refers to 
/var/www/html/sitemgr-site if you moved the directory, or to 
/path/to/phpgroupware/sitemgr/sitemgr-site if you did not). Make a mental note 
of the directory where you put it and the url that it is accessed 
by.</para></listitem><listitem><para>In the sitemgr-site directory is a file 
called config.inc.php. You only have to edit it if you moved the directory. 
Change the value of the line</para><programlisting><![CDATA['phpgw_path'        
   => '../../',
]]></programlisting><para>so that the value of 
&dollar;sitemgr_info&lsqb;'phpgw_path'&rsqb; is 
'/path/to/phpgroupware/'</para></listitem><listitem><para>You're almost set to 
go. Log in to phpGroupWare as an adminis trator. Make sure you gave yourself 
the sitemgr and sitemgr-link applications so that you see them on your navbar. 
Go to the sitemgr application and select &quot;Configure SiteMgr&quot;. Fill in 
&ldquo;URL to sitemgr-site&rdquo; and &ldquo;Filesystem path to sitemgr-site 
directory&rdquo;, and the anonymous user's name and password. Then click on 
save, and you should know select the template for your 
site.</para></listitem><listitem><para>That's it. Go to the Category manager, 
add a category or three and check who can view and edit them, then go to the 
page manager, add a page or three to each category, set up your site header, 
site footer, etc., and go view your recently created site by clicking on the 
sitemgr-link application. Voilà!</para></listitem></orderedlist></sect2>
<sect2><title>Maintenance</title><para>As a site administrator, you have three 
privileges/responsibilies:</para><orderedlist><listitem><para>Define site wide 
content blocks. These are edited in the same interface as category and page 
specific blocks.</para></listitem><listitem><para>Choose permitted modules: If 
you choose &ldquo;Manage site-wide module properties&rdquo; from sitemgr's main 
menu, you will see several rows which all contain four elements: a select box, 
a button labelled &ldquo;Select allowed modules', another select box and a 
button labelled &ldquo;Configure module properties&rdquo;. The first select box 
and its adjacent button in each row permits to choose lists of permitted 
modules. The first row defines a master list for the whole site which is used 
when no more specific lists are found for content areas or categories. The 
following rows each pertain to the different content areas of your site 
template. Here you can choose to allow some modules for one content areas, and 
other modules for another one.
In the category manager, there is a button &ldquo;Manage Modules&rdquo; 
associated with each category. There you can use the same interface to define 
lists specific to one category (and all its subcategories, unless overriden). 
Again you have the choice between one list that pertains to all content areas, 
and specific lists for each category.
When sitemgr has to find a specific value of permitted lists in a given context 
(a given contentarea in a given category) the following algorithm is used: 
First it aks for a value defined for the pair contentarea/category. If none is 
defined, it climbs up the category hierarchy until the site wide value, each 
time looking for a value defined for the pair contentarea/category. If none can 
be found, it returns to the given category the search started from, and now 
asks for values defined for the given category but independent from the 
contentarea. If there is still none defined, it repeats the same traversal up 
the category hierarchy. This means that by simply defining one global master 
list of permitted modules, you can configure the whole site, if you do not need 
more fine grained control.
The lists of permitted lists are never merged, if you define one list for a 
given context, this list is used in this 
context.</para></listitem><listitem><para>Define module properties: The lookup 
algorithm for module properties is exactly the same as for the lists of 
permitted modules. For each module you can set properties for the whole site, 
for content areas, for categories, or for combinations of content areas and 
categories. You access the property editor from the same page where you choose 
the list of permitted modules. You just use the second select box in each row. 
By selecting one module and clicking the &ldquo;Configure module 
properties&rdquo; button, you will open a interface for editing the module's 
properties which ressembles the interface for editing module arguments in the 
content manager. Be aware that only some modules define 
properties.</para></listitem></orderedlist></sect2>
</sect1>
<sect1><title>Template designer manual<anchor 
id="Template-designer-manual"></title><para>One main idea behind sitemgr's 
modularized architecture is that all dynamic content on the website is produced 
by a module. This permits for a very structural way of defining functionality 
and for an easy way of extending functionality. With respect to former versions 
of sitemgr, this means that the templates have to be slightly 
modified:</para><itemizedlist><listitem><para>The whole page template is now 
stored in a file main.tpl in the template's 
directory.</para></listitem><listitem><para>The variables page_content, 
left_blocks,right_blocks have to be replaced by content areas: 
&lcub;contentarea:center&rcub;, &lcub;contentarea:left&rcub;, 
&lcub;contentarea:right&rcub;. Only the contentarea center has a special 
semantics, since it is the hardcoded value for the display of table of contents 
and side index. All other contentareas can have arbitrary names, and you can 
have any practical number of them.</para></listitem><listitem><para>A 
contentarea serves to display the content blocks, the site administrator and 
contributors define. Each contentarea can have its own way of wrapping html 
code around each content block. This at the moment defined in a class that 
implements the transformer interface, i.e. defines a function 
apply_transform(&dollar;title,&dollar;content).This class' name is areaname_bt 
(for blocktransformer) and it is stored in file areaname_bt.inc.php inside the 
template directory. The function apply_transform just has to wrap the desired 
html around the content. It is free to ignore the title, for example the block 
title does not necessarily make sense in a page's central content area. A block 
transformer could apply other transformations to the content, but this would 
probably have counter-intuitive effects on your page's 
contributors.</para></listitem><listitem><para>Other than that a template 
directory can contain template files that are specific to a certain module. For 
example the news module uses a file newsblock.tpl which is a standard API 
template. It is up to a module's developpers what kind of templates he wants to 
use. We propose to use a namespace for these module specific template files. 
For example a template used by module 'news_admin.news' would go into a 
subdirectory 'news_admin/news' in each template directory. If the module does 
not find a template it needs in the site template's directory, it should look 
for a default template file, for example in 
&ldquo;default/news_admin/news'.</para></listitem><listitem><para>You can 
hardcode module calls into the template if your site should have the same 
dynamic content on one specific place.</para></listitem></itemizedlist></sect1>
<sect1><title>Application developper manual<anchor 
id="Application-developper-manual"></title><para>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 
&ldquo;Hello World&rdquo;.</para><programlisting><![CDATA[<?php
]]><![CDATA[
]]><![CDATA[class module_hello extends Module 
]]><![CDATA[{      
]]><![CDATA[    function module_hello()  
]]><![CDATA[    {               
]]><![CDATA[        $this->arguments = array(
]]><![CDATA[            'name' => array(
]]><![CDATA[                'type' => 'textfield', 
]]><![CDATA[                'label' => 'The person to say hello to'
]]><![CDATA[            )
]]><![CDATA[        );
]]><![CDATA[        $this->title = "Hello world";
]]><![CDATA[        $this->description = "This is a simple sample module";   
]]><![CDATA[    }
]]><![CDATA[
]]><![CDATA[    function get_content($arguments,$properties)    
]]><![CDATA[    {
]]><![CDATA[        return lang('Hello') . ' ' . $arguments['name'];
]]><![CDATA[    }
]]><![CDATA[}
]]></programlisting><para>Once your module is registered 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?</para><para>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:</para><variablelist><varlistentry><term>add_transformer(&dollar;transformer)
</term><listitem><para>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 &dollar;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:</para><variablelist><varlistentry><term>apply_transform(&dollar;title,&dollar;content)
</term><listitem><para>A transformer that is not a block transformer should 
normally ignore the title argument, and construct its return value from the 
content 
argument.</para></listitem></varlistentry></variablelist></listitem></varlistentry><varlistentry><term>set_block(&dollar;block,&dollar;produce=False)
</term><listitem><para>This function is called by the content manager (with 
&dollar;produce=False) and by the page generation (with &dollar;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(&dollar;block). 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:</para></listitem></varlistentry></variablelist><programlisting><![CDATA[function
 set_block($block) 
]]><![CDATA[{ 
]]><![CDATA[    parent::set_block($block);
]]><![CDATA[    if ($produce)
]]><![CDATA[    {
]]><![CDATA[        $this->add_transformer(new my_transform());
]]><![CDATA[    }
]]><![CDATA[}
]]></programlisting><variablelist><varlistentry><term>get_properties()
</term><listitem><para>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.</para></listitem></varlistentry><varlistentry><term>get_user_interface()
</term><listitem><para>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.</para></listitem></varlistentry><varlistentry><term>get_admin_interface(&dollar;defaults)
</term><listitem><para>This function creates the interface for editing module 
properties, it works in a similar way to 
get_user_interface.</para></listitem></varlistentry><varlistentry><term>get_translation_interface(&dollar;fromblock,&dollar;toblock)
</term><listitem><para>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.</para></listitem></varlistentry><varlistentry><term>build_input_element((&dollar;input,&dollar;default,&dollar;elementname)
</term><listitem><para>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.</para></listitem></varlistentry><varlistentry><term>validate(&amp;&dollar;data)
</term><listitem><para>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:</para><programlisting><![CDATA[function validate(&$data) 
]]><![CDATA[{ 
]]><![CDATA[    if (preg_match("/[[:upper:]]/",$data['name']))
]]><![CDATA[    {
]]><![CDATA[        $data['name'] = strtolower($data['name']);
]]><![CDATA[        $this->validation_error = "Name has been translated to 
lower case";
]]><![CDATA[    }
]]><![CDATA[    return true;
]]><![CDATA[}
]]></programlisting><para>This would make sure that the module argument name 
would always be 
lowercase.</para></listitem></varlistentry><varlistentry><term>get_content(&amp;&dollar;arguments,&dollar;properties)
</term><listitem><para>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 &dollar;this-&gt;get, &dollar;this-&gt;post, 
&dollar;this-&gt;cookie and &dollar;this-&gt;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 &dollar;arguments array. The 
entries of &dollar;this-&gt;session additionnaly will be stored after 
get_content returns to get_output. This can be very useful if you want your 
module do remain in a stable state while the user interacts with other modules 
on the same page.</para><para>The variables you define in these arrays can be 
identical to those in &dollar;this-&gt;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 
&dollar;this-&gt;get,&dollar;this-&gt;cookie and &dollar;this-&gt;session are 
simple arrays enumerating the variable names, &dollar;this-&gt;post is special 
because it can contain the element definition in the same way as 
&dollar;this-&gt;arguments, which can be used to programatically construct the 
form elements.</para><para>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 you use different modules on 
the same page, that use the same variable names, you would not run into 
problems. 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.</para><programlisting><![CDATA[<?php
]]><![CDATA[
]]><![CDATA[class module_hello extends Module  {
]]><![CDATA[    function module_hello()
]]><![CDATA[    {
]]><![CDATA[        $this->name = "hello";
]]><![CDATA[        $this->arguments = array(
]]><![CDATA[            'name' => array(
]]><![CDATA[                'type' => 'textfield',
]]><![CDATA[                 'label' => 'The person to say hello to'
]]><![CDATA[            )
]]><![CDATA[        );
]]><![CDATA[       $this->post = array('name' => array('type' => 'textfield'));
]]><![CDATA[       $this->session = array('name');
]]><![CDATA[       $this->title = "Hello world";
]]><![CDATA[       $this->description = "This is a simple sample module";
]]><![CDATA[    }
]]><![CDATA[    function get_content(&$arguments,$properties)
]]><![CDATA[    {
]]><![CDATA[       $this->validate($arguments);
]]><![CDATA[       return lang('Hello') . ' ' . $arguments['name'] . '<br><form 
action="' .
]]><![CDATA[           $_SERVER['REQUEST_URI'] . '" method="post">' .
]]><![CDATA[               $this->build_post_element('name',lang('Enter a 
name') .
]]><![CDATA[           '</form>';
]]><![CDATA[    }
]]><![CDATA[
]]><![CDATA[    function validate(&$data)
]]><![CDATA[    {
]]><![CDATA[       if (preg_match("/[[:upper:]]/",$data['name']))
]]><![CDATA[       {
]]><![CDATA[           $data['name'] = strtolower($data['name']);
]]><![CDATA[           $this->validation_error = "Name has been translated to 
lower case";                }
]]><![CDATA[       return true;
]]><![CDATA[   }
]]><![CDATA[}
]]></programlisting></listitem></varlistentry><varlistentry><term>build_post_element(&dollar;key,&dollar;default=False)
</term><listitem><para>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 &dollar;this-&gt;post. If you do not provide a default the current 
blocks value for the argument will be filled 
in.</para></listitem></varlistentry><varlistentry><term>link(&dollar;modulevars)
</term><listitem><para>helps you construct URLS with GET parameters that use 
the service described above. modulevars is an array of variable values keyed on 
variable 
names.</para></listitem></varlistentry><varlistentry><term>get_output(&dollar;type='html')
</term><listitem><para>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.</para></listitem></varlistentry></variablelist><para>To summarize, 
there are the following requirements for a sitemgr 
module:</para><orderedlist><listitem><para>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 phpgroupware 
application.</para></listitem><listitem><para>Its constructor should define the 
following member variables:</para><orderedlist><listitem><para>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.</para></listitem><listitem><para>properties: 
the module's properties the site administrator can edit in order to constrain 
or configure the functionnality of the 
module</para></listitem><listitem><para>title: The module's default title that 
can be overriden for each content 
block.</para></listitem><listitem><para>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).</para></listitem></orderedlist></listitem><listitem><para>It needs a 
get_content function that has access to arguments and properties ans produces 
the block content.</para></listitem><listitem><para>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</para></listitem><listitem><para>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.</para></listitem></orderedlist><para>These are the 
building blocks which should allow for some flexibility in constructing modules 
that make phpgroupware managed data visible on a sitemgr web 
site.</para></sect1>


</article>
--- NEW FILE ---
Introduction to sitemgr modules

January 1, 2003



Abstract

This text provides an overview of sitemgr's proposed 
new modularized architecture and contains the 
information users, administrators, template designers 
and application devellopers need in order to get 
started using sitemgr as a flexible web site managment 
system that can easily make any information and 
business logic phpgroupware knows about publicly 
accessible. This text also serves as a request for 
comments, so that sitemgr's new generation can be 
adapted quickly to the needs of PHPgroupware's user 
community. Please be aware that at the moment the new 
sitemgr is still experimental and that there are some 
areas of its functionnality that need further developpment.

1 Introduction

For the next generaton of phpgroupware's web site 
managment application sitemgr, we propose a new page 
generation architecture whose fundamental idea is that 
all dynamic web site content is built by modules. In 
this section, I will sketch a short outline of how this 
architecture works and I will present the concepts it 
makes use of.

1.1 Template

Sitemgr builds web sites from templates. Those are 
stored in the directory sitemgr/sitemg-site/templates. 
Each of them has a directory of its own. The file 
main.tpl defines the template of the whole site, there 
can be other files that define code for separate areas 
of the page or for specific modules. Templates contain 
four kinds of variables. These are explained here since 
the types 2,3 and 4 can be used both in the template as 
in the page content a module generates.

1. {contentarea: areaname} These define where 
  administrator and contributor provided content go. 
  The names and the number of contentareas a template 
  defines are almost arbitrary.

2. {appname.modulename(?arguments)}These let you 
  hardcode a call to a module into a template. 
  Arguments are in the HTTP GET query string syntax 
  (?key1=value1&key2=value2). At the moment, if you use 
  this type of variables, you have to urlencode the 
  query string yourself. Future versions of sitemgr 
  might provide a simpler notation. For 
  example,{sitemgr.lang_block] creates the select box 
  for multilingual sites.

3. {?(phpgw|sitemgr:)link} This lets you create links 
  either to other pages of your website, or to 
  phpgroupware applications:

  (a) Links to sitemgr either start with '?sitemgr:' or 
    only with '?'. You can either link to a page with 
    {?page_name=downloads] and [?page_id=4}, to a 
    category's index (?category_id=5), to the site 
    index (?index), to the site's table of contents 
    (?toc). Just [?] or {?sitemgr:} links to the 
    administrator defined home page.

  (b) Links to phpgw start with '?phpgw:' . You have to 
    name the application followed by a comma, and 
    optionnally arguments the application can 
    interpret. For example 
    {?phpgw:/addressbook,order=n_given&sort=ASC}.

4. {variable} Finally there are some simple variables 
  you can use to retrieve metainformation about the 
  page or about the user's context:

  (a) {title} the page title

  (b) {subtitle} the page subtitle

  (c) {sitename}the sitename the administrator has 
    chosen for the site

  (d) {footer}the administrator edited footer

  (e) {header}the administrator edited header

  (f) {user}the user's account name

1.2 Module

The main function of a sitemgr module is to generate 
dynamic web site content. To make the development of 
new modules, and the use of modules easy and 
convenient, sitemgr defines an "abstract" class module 
which each module should extend. This parent of all 
modules, provides one essential service: It hooks the 
module into the content managment interface and permits 
the editing of the module's arguments that determine 
what content will be generated. Thus in order to create 
a new module, all you have to do, is to extend the 
abstract super module, define the modules arguments, 
and write a get_content function that returns the 
content that should be displayed on the website. More 
on this in chapter.

1.3 Argument/Content

A module can be seen as a transformation of input 
arguments into generated content. It is important to 
understand that the input arguments can be of 
completely different kinds. On the one hand there can 
be arguments that are as close as possible to the 
generated content. For example the html module's only 
argument is named "htmlcontent" and in normal 
circumstances it is not transformed at all but handed 
over as is to the page generation engine. On the other 
hand arguments can play any conceivable role in the 
generation of content that is driven by data coming 
from other phpgroupware applications. They can be used 
to select between different categories of content, they 
can choose a certain format of presentation, they can 
function as search terms, etc.

1.4 Properties

A module can define properties. Properties are 
accessible to the modules get_content function in the 
same way as arguments, but they differ from them in two ways:

* Properties are edited by the site administrator. 
  Their intended role is to put certain constrains on 
  the workings of the module, so that a site 
  administrator can enforce certain rules. For example 
  the standard html module defines a property called 
  striphtml. If this boolean property is set the module 
  replaces all html in the generated content with entities.

* Properties are not defined with respect to a certain 
  generated content block, but are defined either on a 
  site-wide level or on the level of specific 
  categories. Additionally you can differenciate on 
  each scope properties for each content area. When a 
  content block is generated, properties are searched 
  for in a cascading way, i.e. when the block is 
  specific to a specific page and contentarea and the 
  module's properties are not defined for the 
  combination of the contentarea and the page's 
  category, then properties defined for higher scopes 
  are looked for in a certain order. More on this in chapter.

1.5 Blocks, content areas and scope

There are three ways a module can generate content that 
will be displayed on a web page:

1. A template can contain hardcoded calls to modules 
  that will generate content visible on each page. Thus 
  you could put dynamic content that is visible across 
  the whole site on a place of its own directly into 
  the template. But beware that restrictions defined by 
  the administrator also apply to these hardcoded 
  module calls.

2. A template defines several content areas. This is 
  one important differenced between the modularized 
  sitemgr and previous versions where there were was 
  only one place where contributor edited content went 
  (page_content) and two places for administrator 
  configured blocks (right_blocks, left_blocks). Now 
  templates can define any practical number of content 
  areas with arbitrary names. And there is no more much 
  difference between central and peripheric areas. All 
  can show administrator and contributor provided block 
  content.With one exeption: The name "center" is special 
  in that special pages that get generated by special 
  URLs like "?toc" and "?index" or "?category_id=number" 
  always put there page content (which is internally 
  generated by nothing else than a module) into this 
  content area. If your template does not have a 
  content area called "center" these special URLs won't work.
  Content areas can display module output, as edited by 
  the page's contributors. We refer to each output of a 
  module as a block. Here is another important 
  difference to how sitemgr used to work: Until now 
  there was a sharp distinction between page content 
  which replaces the template variable page_content, 
  and side blocks which got defined in a special file 
  called blockconfig and replaced the template 
  varialbes right_blocks and left_blocks. Now from the 
  perspective of the page generation engine there is no 
  more any difference between content areas, all 
  display blocks of content generated by modules.
  The blocks one content area displays can be defined 
  on different levels of scope: There are site wide 
  blocks that are visible across the whole site, 
  category wide blocks, that are visible on pages that 
  belong to the category or any of its children, and 
  finally are page blocks that define what 
  distinguishes the page from other pages, and normally 
  will be that what you'd call the page's main content.

3. The block content generated by a module can contain 
  template variables of the same type as those that can 
  be hardcoded. This is mostly useful for modules like 
  the html module, where the contributor specified 
  argument is nearly identical to the generated 
  content. Thus a contributor can embed module calls 
  inside the content of a certain block. This is done 
  only once without any recursion, i.e. if a embedded 
  module call returns itself a template variable it is 
  not parsed and processed again.

1.6 Transformer

The architecture for sitemgr modules provides for the 
distinction between some form of raw content a module 
produces and the way it should get displayed on the web 
site, with the future possibility to plug other display 
types into the same framework. The idea is that the raw 
content of a module gets passed through different 
transformers, possibly even several transformers in a 
sequence at the time of content generation. 
Additionally this provides for a use of modules outside 
of sitemgr, for example remote retrieval of information 
with something like XML-RPC. 

At the moment, a module does not need to use 
transformers on its own, it can directly generate html 
content, but if it does, sitemgr provides for an easy 
way to chain different transformers together. Thus a 
module can be constructed in different layers of 
functionality. For example a module's get_content 
function could return data inXML, and it defines a XSLT 
transformation to reorganize this data, and a second 
transformer for creating a user interface for display.

Transformers are also used on the level of the site 
template, insofar as each contentarea can have an 
associated transformer, which wraps the different 
content blocks into a common display format. This does 
the same thing as the file sideblock.tpl in former 
versions of sitemgr.

1.7 Translations

Sitemgr in its new modularized architecture continues 
to be fully multilingual. It is very simple to have a 
new module use this feature. All that is needed is to 
use a special flag in the definition of the module's 
arguments. All arguments that have this flag will be 
stored in a language specific database table, and can 
be translated in the translation manager, very similar 
to the way category and page definitions could already 
be translated to several languages.

2 User manual

The most important difference for site contributors 
between the modularized sitemgr and its older versions 
is that in the page manager now there are two different 
interfaces for each page:

1. When you create a new page or when you click on the 
  Edit button which is associated with an existing 
  page, you no longer edit the page content, but only 
  some basic metainformation about the page as its 
  name, title, subtitle and sort order, and you can 
  change the category the page belongs to.

2. There is a new interface that gets displayed when 
  you click on a page's "Manage content" button. It is 
  here that you create the content blocks for each page.

The second difference is that now a contributor can 
also define content blocks for the whole category he 
has write access for. These category wide blocks will 
be seen on each page that belongs to the category or to 
any of its subcategories. There are also side wide 
content blocks that only the site administrator can create.

The interface for creating content blocks is the same 
on each level of scope, besides that when editing 
blocks on a lower level you can see all the blocks that 
have been defined on a higher level, and will be 
displayed on the website together with the blocks you 
are editing. I will refer to this interface as the 
content manager.

In each content manager, there is a section for each 
content area, where you can add blocks selected from a 
menu of all available modules. Once you have added a 
new block, it appears amidst all other blocks of the 
content area. Those defined on higher level scopes are 
only displayed, those pertaining to the scope 
(site-wide, category or page) you are managing are 
editable. There are four standard interface elements 
you can edit for each block:

  Title Each module defines a default title for blocks 
  it generates. The block title is not necessarily 
  displayed in each content area. It depends on the 
  block transformer defined for the content area by the 
  site template you use. Here you can override the 
  default title with a customized title that will only 
  be used by the block you are editing.

  Actif When you create a new block, it is not 
  immediately visible on the web site. This makes sense 
  since you need to edit its arguments first. When you 
  are finished defining a blocks arguments, you have to 
  check the actif flag to make it visible. This can 
  also be practical if you want to hide some content 
  temporarily from the web site without deleting it 
  from the database.

  Seenby You can control the visibility of each block 
  for the different user roles defined by sitemgr: site 
  administrators, phpgroupware users (which include 
  site administrators) and the anonymous user. 
  Evidently you can also make the block visible for 
  everyone which is the default. 

  Sortorder Here you can change the order in which the 
  blocks are displayed by defining a different integer 
  for each block.

After these, you have to edit the module specific 
arguments, each of which is preceded by an explanatory 
label. The input elements for arguments can be of 
different types: checkboxes, selectboxes, textareas, 
textfields. In the case of text input, you can use the 
same template variables as are used in the site 
template. But be aware that this only works if the 
module puts the same variable into its output, which 
need not necessarily be the case.

3 Administrator manual<Administrator-manual>

3.1 Installation

1. Once you have the sitemgr directory inside your 
  phpgroupware install you can setup it like any other 
  phpgroupware application with the setup program 
  (http://yourmachine/phpgw-path/setup/). You should 
  also install the sitemgr-link application, which is 
  is inside sitemgr and has to be moved up in the 
  directory hierarchy.

  cd sitemgr

  mv sitemgr-link ..

  and then install sitemgr-link with setup

2. Log in to phpGroupWare as an admin and create an 
  anonymous phpgw user and assign it a password. The 
  only app (I assume) that they should have access to 
  is sitemgr-link. sitemgr-link is a dummy application 
  that redirects phpGW users to the generated site.

3. Users who you wish to see sitemgr (aka contributors) 
  must be given acces to sitemgr, users who you want to 
  be able to link to the sitemgr site from phpGW must 
  be given rights to sitemgr-link. The easiest way to 
  do this is to go to User groups and give groups 
  permissions to use the applications. 

4. The sitemgr-site is the directory that serves the 
  dynamic web site. It is located inside sitemgr and 
  works without moving it somewhere else. But it can be 
  located anywhere. For example, you could put it in 
  /var/www/html. You could make the root location of 
  your web server point to it, if you wish (ie, 
  http://yourmachine/ refers to 
  /var/www/html/sitemgr-site if you moved the 
  directory, or to 
  /path/to/phpgroupware/sitemgr/sitemgr-site if you did 
  not). Make a mental note of the directory where you 
  put it and the url that it is accessed by.

5. In the sitemgr-site directory is a file called 
  config.inc.php. You only have to edit it if you moved 
  the directory. Change the value of the line

  'phpgw_path'           => '../../',

  so that the value of $sitemgr_info['phpgw_path'] is 
  '/path/to/phpgroupware/'

6. You're almost set to go. Log in to phpGroupWare as 
  an adminis trator. Make sure you gave yourself the 
  sitemgr and sitemgr-link applications so that you see 
  them on your navbar. Go to the sitemgr application 
  and select "Configure SiteMgr". Fill in "URL to sitemgr-site"
   and "Filesystem path to sitemgr-site directory", and 
  the anonymous user's name and password. Then click on 
  save, and you should know select the template for 
  your site.

7. That's it. Go to the Category manager, add a 
  category or three and check who can view and edit 
  them, then go to the page manager, add a page or 
  three to each category, set up your site header, site 
  footer, etc., and go view your recently created site 
  by clicking on the sitemgr-link application. Voilà!

3.2 Maintenance

As a site administrator, you have three 
privileges/responsibilies:

1. Define site wide content blocks. These are edited in 
  the same interface as category and page specific blocks.

2. Choose permitted modules: If you choose "Manage 
  site-wide module properties" from sitemgr's main menu, 
  you will see several rows which all contain four 
  elements: a select box, a button labelled "Select 
  allowed modules', another select box and a button 
  labelled "Configure module properties". The first 
  select box and its adjacent button in each row 
  permits to choose lists of permitted modules. The 
  first row defines a master list for the whole site 
  which is used when no more specific lists are found 
  for content areas or categories. The following rows 
  each pertain to the different content areas of your 
  site template. Here you can choose to allow some 
  modules for one content areas, and other modules for 
  another one.
  In the category manager, there is a button "Manage Modules"
   associated with each category. There you can use the 
  same interface to define lists specific to one 
  category (and all its subcategories, unless 
  overriden). Again you have the choice between one 
  list that pertains to all content areas, and specific 
  lists for each category.
  When sitemgr has to find a specific value of 
  permitted lists in a given context (a given 
  contentarea in a given category) the following 
  algorithm is used: First it aks for a value defined 
  for the pair contentarea/category. If none is 
  defined, it climbs up the category hierarchy until 
  the site wide value, each time looking for a value 
  defined for the pair contentarea/category. If none 
  can be found, it returns to the given category the 
  search started from, and now asks for values defined 
  for the given category but independent from the 
  contentarea. If there is still none defined, it 
  repeats the same traversal up the category hierarchy. 
  This means that by simply defining one global master 
  list of permitted modules, you can configure the 
  whole site, if you do not need more fine grained control.
  The lists of permitted lists are never merged, if you 
  define one list for a given context, this list is 
  used in this context.

3. Define module properties: The lookup algorithm for 
  module properties is exactly the same as for the 
  lists of permitted modules. For each module you can 
  set properties for the whole site, for content areas, 
  for categories, or for combinations of content areas 
  and categories. You access the property editor from 
  the same page where you choose the list of permitted 
  modules. You just use the second select box in each 
  row. By selecting one module and clicking the "
  Configure module properties" button, you will open a 
  interface for editing the module's properties which 
  ressembles the interface for editing module arguments 
  in the content manager. Be aware that only some 
  modules define properties.

4 Template designer manual<Template-designer-manual>

One main idea behind sitemgr's modularized architecture 
is that all dynamic content on the website is produced 
by a module. This permits for a very structural way of 
defining functionality and for an easy way of extending 
functionality. With respect to former versions of 
sitemgr, this means that the templates have to be 
slightly modified:

* The whole page template is now stored in a file 
  main.tpl in the template's directory.

* The variables page_content, left_blocks,right_blocks 
  have to be replaced by content areas: 
  {contentarea:center}, {contentarea:left}, 
  {contentarea:right}. Only the contentarea center has 
  a special semantics, since it is the hardcoded value 
  for the display of table of contents and side index. 
  All other contentareas can have arbitrary names, and 
  you can have any practical number of them.

* A contentarea serves to display the content blocks, 
  the site administrator and contributors define. Each 
  contentarea can have its own way of wrapping html 
  code around each content block. This at the moment 
  defined in a class that implements the transformer 
  interface, i.e. defines a function 
  apply_transform($title,$content).This class' name is 
  areaname_bt (for blocktransformer) and it is stored 
  in file areaname_bt.inc.php inside the template 
  directory. The function apply_transform just has to 
  wrap the desired html around the content. It is free 
  to ignore the title, for example the block title does 
  not necessarily make sense in a page's central 
  content area. A block transformer could apply other 
  transformations to the content, but this would 
  probably have counter-intuitive effects on your 
  page's contributors.

* Other than that a template directory can contain 
  template files that are specific to a certain module. 
  For example the news module uses a file newsblock.tpl 
  which is a standard API template. It is up to a 
  module's developpers what kind of templates he wants 
  to use. We propose to use a namespace for these 
  module specific template files. For example a 
  template used by module 'news_admin.news' would go 
  into a subdirectory 'news_admin/news' in each 
  template directory. If the module does not find a 
  template it needs in the site template's directory, 
  it should look for a default template file, for 
  example in "default/news_admin/news'.

* You can hardcode module calls into the template if 
  your site should have the same dynamic content on one 
  specific place.

5 Application developper manual<Application-developper-manual>

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 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). 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) 

{ 

    parent::set_block($block);

    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 do 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 you use different modules on the 
  same page, that use the same variable names, you 
  would not run into problems. 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->name = "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.

  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 phpgroupware application.

2. Its constructor should define the following member variables:

  (a) 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.

  (b) properties: the module's properties the site 
    administrator can edit in order to constrain or 
    configure the functionnality of the module

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

  (d) 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 ans 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 
phpgroupware managed data visible on a sitemgr web site.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]