Sortieren von (Template) Bereichen

Dieser Programmteil bietet die Möglichkeit den HTML-Quelltext der drei CPs

  • Bilder <div>
  • Bilder spezial
  • Register-Tabs

blockweise umzusortieren.

Somit ist es nun möglich, z.B. für den CP Register-Tabs gängige Tab-Erweiterungen einzusetzen.

Ein Beispiel für den Einsatz im CP “Bilder <div>” ist hier veranschaulicht: Einfache CSS-Galerie (no JS) (Einfache Ausführung des PHP-Scripts).



Docu: –
Forum: –

Autor: K.Heermann (flip-flop) http://planmatrix.de
CMS Version: >= 1.4x
Version: V1.1 (09.02.2010)
Update: V1.2 (15.02.2010)
* Genereller CP Identifizierer <!--SORT_INTO_NEW_BLOCKS_V12//-->
* Erstes IF geändert um immer alle drei CPs zu erfassen 29,31,32

Update: V1.3 (20.02.2010)
* Nur notwendig für sehr spezielle JavaScriptanwendungen
* Genereller CP Identifizierer geändert von <!--SORT_INTO_NEW_BLOCKS//--> nach <!--SORT_INTO_NEW_BLOCKS_V13//-->

Download-PHP: cp_trig_sort_section_v12.zip (1.98 KiB, 96 downloads) (V1.2)
Download-PHP: cp_trig_sort_section_v13.zip (2.49 KiB, 111 downloads) (V1.3)

Bedingung:/config/phpwcms/conf.inc.php

  • $phpwcms['allow_ext_init'] = 1;
  • $phpwcms['allow_cntPHP_rt'] = 1;


Beispiel Register Tabs:

Backend:

Frontend:

Normale Ausgabe:

- Links FE-Ausgabe - Rechts Quelltext gekürzt

Quelltext ungekürzt

<h3>Register Tab</h3>
 
<dl id="tab84" class="tabs">
    <dt id="title-"><b>Reg01</b></dt>
 
    <dd id="content-">
        <h3>Register 01</h3>
        <p>Text&nbsp; Reg01</p>
    </dd>
 
<div style="border-bottom: 1px dotted rgb(170, 170, 170); margin: 0pt 0pt 15px; clear: both;"></div>
 
    <dt id="title-"><b>Reg02</b></dt>
 
    <dd id="content-">
        <h3>Register 02</h3>
        <p>Text&nbsp; Reg02</p>
    </dd>
 
<div style="border-bottom: 1px dotted rgb(170, 170, 170); margin: 0pt 0pt 15px; clear: both;"></div>
 
    <dt id="title-"><b>Reg03</b></dt>
 
    <dd id="content-">
        <h3>Register 03</h3>
        <p>Text&nbsp; Reg03</p>
    </dd>
 
<div style="border-bottom: 1px dotted rgb(170, 170, 170); margin: 0pt 0pt 15px; clear: both;"></div>
 
    <dt id="title-"><b>New Title</b></dt>
 
    <dd id="content-">
        <h3>Register 04</h3>
        <p>Text&nbsp; Reg04</p>
    </dd>
 
<div style="border-bottom: 1px dotted rgb(170, 170, 170); margin: 0pt 0pt 15px; clear: both;"></div>
 
    <dt id="title-"><b>Reg05</b></dt>
 
    <dd id="content-">
        <h3>Register 05</h3>
        <p>Text&nbsp; Reg05</p>
    </dd>
 
<div style="border-bottom: 1px dotted rgb(170, 170, 170); margin: 0pt 0pt 15px; clear: both;"></div>
 
</dl>

Sortiere Ausgabe:

- Links FE-Ausgabe - Rechts Quelltext gekürzt

Quelltext ungekürzt

<h3>Register Tab</h3>
 
 
<dl id="tab84" class="tabs"><!--new_sort_order//-->
<div id="SECTION-01">
 
    <dt id="title-1"><b>Reg01</b></dt>
    <dt id="title-2"><b>Reg02</b></dt>
    <dt id="title-3"><b>Reg03</b></dt>
    <dt id="title-4"><b>New Title</b></dt>
    <dt id="title-5"><b>Reg05</b></dt>
</div>
 
<div id="SECTION-02">
 
    <dd id="content-1">
        <h3>Register 01</h3>
        <p>Text&nbsp; Reg01</p>
    </dd>
 
    <dd id="content-2">
        <h3>Register 02</h3>
        <p>Text&nbsp; Reg02</p>
    </dd>
 
 
    <dd id="content-3">
        <h3>Register 03</h3>
        <p>Text&nbsp; Reg03</p>
    </dd>
 
 
    <dd id="content-4">
        <h3>Register 04</h3>
        <p>Text&nbsp; Reg04</p>
    </dd>
 
    <dd id="content-5">
        <h3>Register 05</h3>
        <p>Text&nbsp; Reg05</p>
    </dd>
 
</div>
 
<div id="Trara-Nix">
    <div style="border-bottom: 1px dotted rgb(204, 204, 204); margin: 0pt 0pt 15px; clear: both;"></div>
    <div style="border-bottom: 1px dotted rgb(204, 204, 204); margin: 0pt 0pt 15px; clear: both;"></div>
    <div style="border-bottom: 1px dotted rgb(204, 204, 204); margin: 0pt 0pt 15px; clear: both;"></div>
    <div style="border-bottom: 1px dotted rgb(204, 204, 204); margin: 0pt 0pt 15px; clear: both;"></div>
    <div style="border-bottom: 1px dotted rgb(204, 204, 204); margin: 0pt 0pt 15px; clear: both;"></div>
</div>
 
</dl>

Neue Tags:

Im Template werden einige neue Tags eingesetzt auf die das PHP-Script reagieren kann.

Grundsätzlich sind es drei Bereiche die erfasst werden müssen:

  1. Der Definitionsteil [CP_TRIG_DEFINITION] in dem bestimmt wird wie die Vor/Nach-Anweisungen für die neu zusammengestellten Blöcke aussehen (Muss in einem sich nicht wiederholenden Teil des Templates stehen)
    • Hier befinden sich die Einzelanweisungen für die fertigen Blöcke [BLOCK_01X_PREFIX] ….. [/BLOCK_01X_PREFIX], [BLOCK_01X_SUFFIX] ….. [/BLOCK_01X_SUFFIX], …. usw.
  2. Der Umschließerteil [CP_TRIG_WRAP_CONTENT] der durch den neu sortierten Quelltext ersetzt wird
  3. Der Contentteil [CP_TRIG_CONTENT] in dem das Script jeweils nach den gekennzeichneten Bereichen sucht
    • Die gekennzeichneten Bereiche [BLOCK_01X], [BLOCK_02X], … usw.
  4. Ein Zähler [COUNTX], mir dem eindeutig die ehemalige Zugehörigkeit der einzelnen Elemente in jedem fertigen Block bestimmt werden kann


Grundschema:

[CP_TRIG_DEFINITION]                         // Begin Definiton

  [BLOCK_01X_PREFIX] ..... [/BLOCK_01X_PREFIX]        // Block01 before
  [BLOCK_01X_SUFFIX] ..... [/BLOCK_01X_SUFFIX]        // Block01 after

  [BLOCK_02X_PREFIX] ..... [/BLOCK_02X_PREFIX]        // Block02 before
  [BLOCK_02X_SUFFIX] ..... [/BLOCK_02X_SUFFIX]        // Block02 after

  [BLOCK_NIXX_PREFIX] .... [/BLOCK_NIXX_PREFIX]       // Block03 before
  [BLOCK_NIXX_SUFFIX] .... [/BLOCK_NIXX_SUFFIX]       // Block03 after

[/CP_TRIG_DEFINITION]                        // End Definiton

[CP_TRIG_WRAP_CONTENT]                       // Begin where the result is placed into

  [CP_TRIG_CONTENT]                            // Begin Section

    [BLOCK_01X] ..... [/BLOCK_01X]                      // designated area
    [BLOCK_02X] ..... [/BLOCK_02X]                      // designated area
    [BLOCK_NIXX] .... [/BLOCK_NIXX]                     // designated area

    [COUNTX]                                     // Running Counter >0

  [/CP_TRIG_CONTENT]                           // End Section

[/CP_TRIG_WRAP_CONTENT]                      // End where the result is placed into

Template:

Dateiname: tab_sort_section_v12.tmpl
Ort: template/inc_cntpart/tabs/

Hier müssen noch die Wrapper-Tags eingesetzt werden:

tab_sort_section_v12.tmpl

<!--TABS_START//-->
<!--SORT_INTO_NEW_BLOCKS_V12//-->
 
[TITLE]<h3>{TITLE}</h3>[/TITLE]
[SUBTITLE]<h4>{SUBTITLE}</h4>[/SUBTITLE]
 
[CP_TRIG_DEFINITION]
 
[BLOCK_01X_PREFIX]<div id="SECTION-01">    [/BLOCK_01X_PREFIX]
[BLOCK_01X_SUFFIX]</div>                [/BLOCK_01X_SUFFIX]
 
[BLOCK_02X_PREFIX]<div id="SECTION-02">    [/BLOCK_02X_PREFIX]
[BLOCK_02X_SUFFIX]</div>                [/BLOCK_02X_SUFFIX]
 
[BLOCK_NIXX_PREFIX]<div id="Trara-Nix">    [/BLOCK_NIXX_PREFIX]
[BLOCK_NIXX_SUFFIX]</div>                [/BLOCK_NIXX_SUFFIX]
 
[/CP_TRIG_DEFINITION]
 
[TABS_ENTRIES]
 
<dl id="tab{ID}" class="tabs">
[CP_TRIG_WRAP_CONTENT]
{TABS_ENTRIES}
[/CP_TRIG_WRAP_CONTENT]
</dl>
 
[/TABS_ENTRIES]
<!--TABS_END//-->
 
 
<!--TABS_ENTRY_START//-->
 
[CP_TRIG_CONTENT]
 
[BLOCK_01X]
    <dt id="title-[COUNTX]">
        [TABTITLE]<b>{TABTITLE}</b>[/TABTITLE][TABTITLE_ELSE]<b>New Title</b>[/TABTITLE_ELSE]
    </dt>
[/BLOCK_01X]
 
[BLOCK_02X]
    [TABCONTENT]<dd id="content-[COUNTX]">
        [TABHEADLINE]<h3>{TABHEADLINE}</h3>[/TABHEADLINE]
        [TABTEXT]{TABTEXT}[/TABTEXT]
    </dd>[/TABCONTENT]
[/BLOCK_02X]
 
[BLOCK_NIXX]
    <div style="clear:both; margin: 0 0 15px 0; border-bottom: 1px dotted #ccc;"></div>
[/BLOCK_NIXX]
 
[/CP_TRIG_CONTENT]
 
<!--TABS_ENTRY_END//-->

<note important> Wichtig:

<!--SORT_INTO_NEW_BLOCKS_V12//-->

muss im Template und im PHP-Script identisch eingetragen werden um dieses Script genau für dieses Template zu identifizieren. </note>

<note> Bitte auf Namensgleichheit für die Tags im Template und im PHP-Script achten - Bsp.:

  • Template:
    • [BLOCK_02X_SUFFIX]
    • [BLOCK_02X]


  • PHP-Script:
    • $sec[2] = 'BLOCK_02X';

</note>

PHP Script V1.2:

Dateiname: cp_trig_sort_section_v12.php
Verzeichnis: template/inc_script/frontend_init/

cp_trig_sort_section_v12.php

<?php
// -------------------------------------------------------------------------------------------
// obligate check for phpwcms constants
  if (!defined('PHPWCMS_ROOT')) {die("You Cannot Access This Script Directly, Have a Nice Day.");}
// -------------------------------------------------------------------------------------------
 
/**
 * * -------------------------------------------------------------------------------------------
 * Sort particular sections into separate blocks
 * V1.1  09.02.10 K.Heermann  http://planmatrix.de
 * Update: 15.02.10 V1.2
 * - new general cp identifier <!--SORT_INTO_NEW_BLOCKS_V12//-->
 * - change first "if statement" to all three cp´s 29,31,32
 * ------------------------------------------------------------------------------------------- */
 
 
function CP_TRIG_SORT_SECTION_V12($text, & $data) {
//function CP_IMAGES_SORT_THUMBS_AND_IMAGES($text, & $data) {
 
// ======= CUSTOM vars ========================================================
 
$cp_identification     = '<!--SORT_INTO_NEW_BLOCKS//-->';  // cp identifier
 
// use only if the CP IDs should be indicated (very fast)
// $cp_cpID            = array(14,25,116);
 
$sec[1]             = 'BLOCK_01X';                // wrapper of the first section
$sec[2]             = 'BLOCK_02X';                // wrapper of the second section
 
// Only an estupid example, kill this entry)
$sec[3]             = 'BLOCK_NIXX';                // wrapper of the third section
// ============================================================================
 
 
    // CP: 29 => image <div>   CP: 31 => image special    CP: 32 => register tabs
    if(($data['acontent_type'] == 29
     OR $data['acontent_type'] == 31
     OR $data['acontent_type'] == 32) AND strpos($text, $cp_identification) ) {
 
    // use only if the CP IDs should be indicated (very fast)
//    if (in_array ($data['acontent_id'],$cp_cpID) ) {
 
        $_text = array();
 
        // Catch the content area from template
        preg_match_all('/\[CP_TRIG_CONTENT\](.*?)\[\/CP_TRIG_CONTENT\]/ism',$text, $_text['content_area']);
 
        if ($_text['content_area'][1][0]) {  // is there any content?
 
            // some parameters ---------
            $defsec = array();
 
            foreach ($sec as $key=>$value) {
 
                $defsec[$key]['pref']     = $value.'_PREFIX';    // prefix for the first section
                $defsec[$key]['suff']     = $value.'_SUFFIX';    // suffix for the first section
            }
 
 
            // Catch content section by section and sort into the right block --------
 
            foreach ( $_text['content_area'][1] as $key01 => $value01 ) {
 
                foreach ($sec as $key02=>$value02) {
                    // parsing particular section
                    preg_match('/\['.$value02.'\](.*?)\[\/'.$value02.'\]/ism',$value01, $_temp);
                    $_temp[1] = str_replace('[COUNTX]', $key01+1, $_temp[1]);
                    $_text['content'][$key02] .= $_temp[1].LF;
 
                }
            }
 
 
            // Parsing the definition list ----------------------------------
 
            preg_match_all('/\[CP_TRIG_DEFINITION\](.*?)\[\/CP_TRIG_DEFINITION\]/ism',$text, $_text['definition']);
 
            if ($_text['definition'][1][0]) {  // is there any content in definition section?
 
 
                foreach ($defsec as $key=>$value) {
 
                    if (preg_match('/\['.$value['pref'].'\](.*?)\[\/'.$value['pref'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] = $_temp[1] . $_text['content'][$key];
                    else $_text['content'][$key] = LF.'<!-- no definiton begin //-->'.LF . $_text['content'][$key];
 
                    if (preg_match('/\['.$value['suff'].'\](.*?)\[\/'.$value['suff'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] .= $_temp[1];
                    else $_text['content'][$key] .= '<!--no definiton end //-->'.LF;
 
                }
 
            }
 
 
            // Kill all DEFINITION entries in template
            $text = preg_replace('/\[CP_TRIG_DEFINITION\](.*?)\[\/CP_TRIG_DEFINITION\]/ism', '', $text);
 
            // Insert new sorted content ------------------------------------
            $_temp = '';
            foreach ($_text['content'] as $value) {
                $_temp .= LF.$value;
            }
 
 
            $text = preg_replace('/\[CP_TRIG_WRAP_CONTENT\](.*?)\[\/CP_TRIG_WRAP_CONTENT\]/ism', '<!--new_sort_order//-->'.$_temp, $text);  // fill content
        }
    }
 
    return $text;
 
} // ---- END function
 
register_cp_trigger('CP_TRIG_SORT_SECTION_V12');
 
?>


PHP Script V1.3:

* Update: 20.02.10 V1.3
  * Identifizierer von <!--SORT_INTO_NEW_BLOCKS//--> nach <!--SORT_INTO_NEW_BLOCKS_V13//--> geändert.
  * Neuer Zähler um die Gesamtsumme der Tabs zu erhalten [COUNTX_TOTAL] (Für spezielle JS Anwedungen. 
  * Neue Platzhalter [CLASS_0yX_FIRST/LAST] z.B. 
    * Definition: [CLASS_01X_FIRST]......[/CLASS_01X_FIRST]
    * Platzhalter: [CLASS_01X_FIRST] 
  * In die erste und/oder letzte Zeile (Tab) eines Blocks können Strings eingefügt werden (z.B.:class="active") 

Das Update ist nur notwendig für Scripte die z.B. eine spezielle Klasse im ersten oder/und letzten Tab beim ersten Seitenaufruf benötigen.
→ Z.B.: nuTabs (MooTools v1.2x)

<note> UPdate V1.3:

Identifizierer
von <!--SORT_INTO_NEW_BLOCKS//-->
nach <!--SORT_INTO_NEW_BLOCKS_V13//--> geändert :!:

Bitte auf Namensgleichheit für die Tags im Template und im PHP-Script achten - Bsp.:

  • Template:
    • [BLOCK_02X_SUFFIX] // Definition
    • [BLOCK_02X] // Platzhalter
    • [CLASS_02X_FIRST] // Definition
    • [CLASS_02X_FIRST] // Platzhalter


  • PHP-Script:
    • $sec[2] = 'BLOCK_02X';
    • $cla[2] = 'CLASS_02X';

</note>

Dateiname: cp_trig_sort_section_v13.php
Ort: template/inc_script/frontend_init/

cp_trig_sort_section_v13.php

<?php
// -------------------------------------------------------------------------------------------
// obligate check for phpwcms constants
  if (!defined('PHPWCMS_ROOT')) {die("You Cannot Access This Script Directly, Have a Nice Day.");}
// -------------------------------------------------------------------------------------------
 
/**
 * * -------------------------------------------------------------------------------------------
 * Sort particular sections into separate blocks
 * V1.1  09.02.10 K.Heermann  http://planmatrix.de
 * Update: 15.02.10 V1.2
 * - new general cp identifier <!--SORT_INTO_NEW_BLOCKS//-->
 * - change first "if statement" to all three cp´s 29,31,32
 * Update: 20.02.10 V1.3
 * - Indetifier changed from <!--SORT_INTO_NEW_BLOCKS//--> to <!--SORT_INTO_NEW_BLOCKS_V13//-->
 * - new counter for "Total number tabs" [COUNTX_TOTAL] for some specail JS.
 * - new [CLASS_0yX_FIRST/LAST] placeholder e.g. [CLASS_01X_FIRST]...[/CLASS_01X_FIRST], [CLASS_02X]
 * . for every block to inject strings (eg.:class="active") into the first and/or last tab
 * ------------------------------------------------------------------------------------------- */
 
 
function CP_TRIG_SORT_SECTION_V13($text, & $data) {
//function CP_IMAGES_SORT_THUMBS_AND_IMAGES($text, & $data) {
 
// ======= CUSTOM vars ========================================================
 
$cp_identification     = '<!--SORT_INTO_NEW_BLOCKS_V13//-->';  // cp identifier
 
// use only if the CP IDs should be indicated (very fast)
// $cp_cpID            = array(14,25,116);
$sec[1]             = 'BLOCK_01X';                // wrapper of the first section
$cla[1]                = 'CLASS_01X';                // class for the first/last line in block
$sec[2]             = 'BLOCK_02X';                // wrapper of the second section
$cla[2]                = 'CLASS_02X';                // class for the first/last line in block
 
// Only an estupid example, kill this entry)
$sec[3]             = 'BLOCK_NIXX';                // wrapper of the third section
$cla[3]                = 'CLASS_NIXX';                // class for the first/last line in block
// ============================================================================
 
 
    // CP: 29 => image <div>   CP: 31 => image special    CP: 32 => register tabs
 
    if(($data['acontent_type'] == 29
     OR $data['acontent_type'] == 31
     OR $data['acontent_type'] == 32) AND strpos($text, $cp_identification) ) {
 
    // use only if the CP IDs should be indicated (very fast)
//    if (in_array ($data['acontent_id'],$cp_cpID) ) {
 
        $_text = array();
 
        // Catch the content area from template
 
        preg_match_all('/\[CP_TRIG_CONTENT\](.*?)\[\/CP_TRIG_CONTENT\]/ism',$text, $_text['content_area']);
 
        if ($_text['content_area'][1][0]) {  // is there any content?
 
            // some parameters ---------
            $defsec = array();
            $_count = count($_text['content_area'][1]);
 
            foreach ($sec as $key=>$value) {
 
                $defsec[$key]['pref']     = $value.'_PREFIX';    // prefix for the first section
                $defsec[$key]['suff']     = $value.'_SUFFIX';    // suffix for the first section
                $defcla[$key]['first']     = $cla[$key].'_FIRST';    // e.g. class only for the first line entry
                $defcla[$key]['last']     = $cla[$key].'_LAST';    // e.g. class only for the last line entry
            }
 
            // Catch content section by section and sort into the right block --------
 
            foreach ( $_text['content_area'][1] as $key01 => $value01 ) {
 
                foreach ($sec as $key02=>$value02) {
                    // parsing particular section
                    preg_match('/\['.$value02.'\](.*?)\[\/'.$value02.'\]/ism',$value01, $_temp);
 
                    $_temp[1] = str_replace('[COUNTX]', $key01+1, $_temp[1]);  // insert running counter
 
                    // kill placeholder CLASS in all lines > first line and < last line
                    if ($key01 > 0)         $_temp[1] = str_replace('['.$defcla[$key02]['first'].']','', $_temp[1]);
                    if ($key01 < $_count-1) $_temp[1] = str_replace('['.$defcla[$key02]['last'].']' ,'', $_temp[1]);
 
                    $_text['content'][$key02] .= $_temp[1].LF;
 
                }
            }
 
 
            // Parsing the definition list ----------------------------------
 
            preg_match_all('/\[CP_TRIG_DEFINITION\](.*?)\[\/CP_TRIG_DEFINITION\]/ism',$text, $_text['definition']);
 
            if ($_text['definition'][1][0]) {  // is there any content in definition section?
 
                foreach ($defsec as $key=>$value) {
 
                    if (preg_match('/\['.$value['pref'].'\](.*?)\[\/'.$value['pref'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] = $_temp[1] . $_text['content'][$key];  // Davorsetzen
                    else $_text['content'][$key] = LF.'<!-- no definiton begin //-->'.LF . $_text['content'][$key];
 
                    if (preg_match('/\['.$value['suff'].'\](.*?)\[\/'.$value['suff'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] .= $_temp[1];  // Anhaengen
                    else $_text['content'][$key] .= '<!--no definiton end //-->'.LF;
 
                    // CLASS available ?  -> replace the CLASS_yX_FIRST and CLASS_yX_LAST
                    if (preg_match('/\['.$defcla[$key]['first'].'\](.*?)\[\/'.$defcla[$key]['first'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] = str_replace('['.$defcla[$key]['first'].']',$_temp[1],$_text['content'][$key]);
 
                    if (preg_match('/\['.$defcla[$key]['last'].'\](.*?)\[\/'.$defcla[$key]['last'].'\]/ism',$_text['definition'][1][0], $_temp))
                        $_text['content'][$key] = str_replace('['.$defcla[$key]['last'].']',$_temp[1],$_text['content'][$key]);
                }
 
            }
 
 
            // Kill all DEFINITION entries in template
 
            $text = preg_replace('/\[CP_TRIG_DEFINITION\](.*?)\[\/CP_TRIG_DEFINITION\]/ism', '', $text);
 
            // Insert new sorted content ------------------------------------
            $_temp = '';
            foreach ($_text['content'] as $value) {
                $_temp .= LF.$value;
            }
 
 
            $text = preg_replace('/\[CP_TRIG_WRAP_CONTENT\](.*?)\[\/CP_TRIG_WRAP_CONTENT\]/ism', '<!--new_sort_order//-->'.$_temp, $text);  // fill content
            $text = str_replace ('[COUNTX_TOTAL]',$key01+1, $text);  // Set COUNTX_SUM (block count) outsite my range e.g. in PHP Section :)
        }
    }
 
    return $text;
 
} // ---- END function
 
register_cp_trigger('CP_TRIG_SORT_SECTION_V13');
 
?>
deutsch/ersetzer_rts/frontend_init/cp_trigger/sort-section.txt · Last modified: 2018/06/03 18:09 (external edit)
www.planmatrix.de www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0