[Top][All Lists]
[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 ---
÷À;
Õn0
â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
ÙM0
ÜÒ0
PtypeasthosethatcanbeharÑðdcoded.Thisismostlyusefulformoduleslike¡H
ÜÒ0
#rawcontentamoduleprÑðoducesandthewayitshouldgetdisplayedontheweb¡0
ÜÒ0
ÙM0
àinterfaceforcrÑðeatingcontentblocksisthesameoneachlevelofscope,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Ñðeturnstrëue.Whenyouoverridethisfunction,youcanaltertheargu-¡D
b>
ÌÌ{¡Yfunctionffmodule_hello()¡Y{¡o30$this->nameff="hello";¡o30$this->argumentsff=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&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&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 “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<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 “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.</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 “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.</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
>“Manage content” 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' => '../../',</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 “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.</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 “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.</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 “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.</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 “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 “Hello World”.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
><?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'];
}
}</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->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(&$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(&$data)
{
if (preg_match("/[[:upper:]]/",$data['name']))
{
$data['name'] = strtolower($data['name']);
$this->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(&$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->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.</P
><P
>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.</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"
><?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;
}
}</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->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}è¾BoMz³÷Ëc[h
$úLËlxEÊ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áòîlvV¦Ñ]¸#VpmÐûê:^V0Â,Cg
:gA÷êqFÔDÌ5ñÍoo· &pÄ)2³¯a?qÉàù`Új·`LS$¢jÁ.T³
ªojÈù2AJÍÁ©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>{contentarea: areaname}
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>{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.</para></listitem><listitem><para>{?(phpgw|sitemgr:)link} 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
{?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.</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
{?phpgw:/addressbook,order=n_given&sort=ASC}.</para></listitem></orderedlist></listitem><listitem><para>{variable}
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>{title} the page
title</para></listitem><listitem><para>{subtitle} the page
subtitle</para></listitem><listitem><para>{sitename}the sitename the
administrator has chosen for the
site</para></listitem><listitem><para>{footer}the administrator
edited footer</para></listitem><listitem><para>{header}the
administrator edited
header</para></listitem><listitem><para>{user}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
“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<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
“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.</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
“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.</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 “Manage
content” 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
$sitemgr_info['phpgw_path'] 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 "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.</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 “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.</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 “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.</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:
{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.</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($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.</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
“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
“Hello World”.</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($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 $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($title,$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($block,$produce=False)
</term><listitem><para>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:</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($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($fromblock,$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(($input,$default,$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(&$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(&$arguments,$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 $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.</para><para>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.</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($key,$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 $this->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($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($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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [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,
Michael Totschnig <address@hidden> <=
- Prev by Date:
[Phpgroupware-cvs] CVS: sitemgr/inc class.Categories_UI.inc.php,NONE,1.1 class.Common_BO.inc.php,NONE,1.1 class.Content_BO.inc.php,NONE,1.1 class.Content_SO.inc.php,NONE,1.1 class.Content_UI.inc.php,NONE,1.1 class.Modules_BO.inc.php,NONE,1.1 class.Modules_SO.inc.php,NONE,1.1 class.Modules_UI.inc.php,NONE,1.1 class.Pages_UI.inc.php,NONE,1.1 class.SiteContent_UI.inc.php,NONE,1.1 class.Translations_UI.inc.php,NONE,1.1 class.browser_transform.inc.php,NONE,1.1class.module.inc.php,NONE,1.1 class.module_administration.inc.php,NONE,1.1 class.module_amazon.inc.php,NONE,1.1class.module_appdir.inc.php,NONE,1.1 class.module_calendar.inc.php,NONE,1.1 class.module_currentsection.inc.php,NONE,1.1 class.module_forum.inc.php,NONE,1.1class.module_galerie.inc.php,NONE,1.1 class.module_google.inc.php,NONE,1.1class.module_hello.inc.php,NONE,1.1 class.module_html.inc.php,NONE,1.1class.module_index.inc.php,NONE,1.1 class.module_index_block.inc.php,NONE,1.1 class.module_lang_block.inc.php,NONE,1.1 class.module_login.inc.php,NONE,1.1class.module_meta.inc.php,NONE,1.1 class.module_news.inc.php,NONE,1.1class.module_sitetree.inc.php,NONE,1.1 class.module_toc.inc.php,NONE,1.1class.module_toc_block.inc.php,NONE,1.1 class.module_xml.inc.php,NONE,1.1 class.xmltool2.inc.php,NONE,1.1 class.xslt_transform.inc.php,NONE,1.1 class.ACL_BO.inc.php,1.1.1.1,1.2 class.ACL_SO.inc.php,1.2,1.3 class.Block_SO.inc.php,1.1,1.2 class.Categories_BO.inc.php,1.5,1.6 class.Categories_SO.inc.php,1.11,1.12 class.Common_UI.inc.php,1.7,1.8 class.MainMenu_UI.inc.php,1.5,1.6 class.Page_SO.inc.php,1.4,1.5 class.Pages_BO.inc.php,1.3,1.4 class.Pages_SO.inc.php,1.9,1.10 class.Theme_BO.inc.php,1.3,1.4 class.sitePreference_SO.inc.php,1.2,1.3 hook_admin.inc.php,1.1.1.1,1.2 hook_preferences.inc.php,1.1.1.1,1.2 class.Admin_ManageCategories_UI.inc.php,1.6,NONE class.Blocks_BO.inc.php,1.2,NONE class.Blocks_SO.inc.php,1.1,NONE class.Categories_db_SO.inc.php,1.7,NONE class.admin_ManageSiteContent_UI.inc.php,1.2,NONE class.contributor_ManagePage_UI.inc.php,1.8,NONE
- Next by Date:
[Phpgroupware-cvs] CVS: sitemgr/sitemgr-site config.inc.php,NONE,1.1 functions.inc.php,1.3,1.4 index.php,1.5,1.6 config.inc.php.template,1.6,NONE
- Previous by thread:
[Phpgroupware-cvs] CVS: sitemgr/inc class.Categories_UI.inc.php,NONE,1.1 class.Common_BO.inc.php,NONE,1.1 class.Content_BO.inc.php,NONE,1.1 class.Content_SO.inc.php,NONE,1.1 class.Content_UI.inc.php,NONE,1.1 class.Modules_BO.inc.php,NONE,1.1 class.Modules_SO.inc.php,NONE,1.1 class.Modules_UI.inc.php,NONE,1.1 class.Pages_UI.inc.php,NONE,1.1 class.SiteContent_UI.inc.php,NONE,1.1 class.Translations_UI.inc.php,NONE,1.1 class.browser_transform.inc.php,NONE,1.1class.module.inc.php,NONE,1.1 class.module_administration.inc.php,NONE,1.1 class.module_amazon.inc.php,NONE,1.1class.module_appdir.inc.php,NONE,1.1 class.module_calendar.inc.php,NONE,1.1 class.module_currentsection.inc.php,NONE,1.1 class.module_forum.inc.php,NONE,1.1class.module_galerie.inc.php,NONE,1.1 class.module_google.inc.php,NONE,1.1class.module_hello.inc.php,NONE,1.1 class.module_html.inc.php,NONE,1.1class.module_index.inc.php,NONE,1.1 class.module_index_block.inc.php,NONE,1.1 class.module_lang_block.inc.php,NONE,1.1 class.module_login.inc.php,NONE,1.1class.module_meta.inc.php,NONE,1.1 class.module_news.inc.php,NONE,1.1class.module_sitetree.inc.php,NONE,1.1 class.module_toc.inc.php,NONE,1.1class.module_toc_block.inc.php,NONE,1.1 class.module_xml.inc.php,NONE,1.1 class.xmltool2.inc.php,NONE,1.1 class.xslt_transform.inc.php,NONE,1.1 class.ACL_BO.inc.php,1.1.1.1,1.2 class.ACL_SO.inc.php,1.2,1.3 class.Block_SO.inc.php,1.1,1.2 class.Categories_BO.inc.php,1.5,1.6 class.Categories_SO.inc.php,1.11,1.12 class.Common_UI.inc.php,1.7,1.8 class.MainMenu_UI.inc.php,1.5,1.6 class.Page_SO.inc.php,1.4,1.5 class.Pages_BO.inc.php,1.3,1.4 class.Pages_SO.inc.php,1.9,1.10 class.Theme_BO.inc.php,1.3,1.4 class.sitePreference_SO.inc.php,1.2,1.3 hook_admin.inc.php,1.1.1.1,1.2 hook_preferences.inc.php,1.1.1.1,1.2 class.Admin_ManageCategories_UI.inc.php,1.6,NONE class.Blocks_BO.inc.php,1.2,NONE class.Blocks_SO.inc.php,1.1,NONE class.Categories_db_SO.inc.php,1.7,NONE class.admin_ManageSiteContent_UI.inc.php,1.2,NONE class.contributor_ManagePage_UI.inc.php,1.8,NONE
- Next by thread:
[Phpgroupware-cvs] CVS: sitemgr/sitemgr-site config.inc.php,NONE,1.1 functions.inc.php,1.3,1.4 index.php,1.5,1.6 config.inc.php.template,1.6,NONE
- Index(es):