DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:template

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
plugin:template [2006-11-09 20:04] – old revision restored andiplugin:template [2019-09-10 20:05] (current) Aleksandr
Line 1: Line 1:
 +====== Template Extension for Command Plugin ======
  
 +---- plugin ----
 +description: Render a data set from a template
 +author     : Spider Joe
 +email      : 
 +type       : syntax
 +lastupdate : 2005-09-09
 +compatible : 
 +depends    : command
 +conflicts 
 +similar    : 
 +tags       : extension, command, template
 +
 +downloadurl: 
 +bugtracker : 
 +sourcerepo : 
 +donationurl: 
 +
 +screenshot_img: 
 +----
 +
 +===== Overview =====
 +
 +The **Template Command** renders a data set from a template. The data set is just a DokuWiki page containing a series of lists representing records (<del>[[http://www.spiderjoe.com/spiders/calendar?do=edit|example]]</del>). The template is a PHP file in ''lib/tpl/'' that generates either HTML or DokuWiki [[:wiki:syntax]] for inclusion at the place of the template command (<del>[[http://www.spiderjoe.com/spiders/calendar|example]]</del>). The command is an extension of the [[plugin:command|Command Plugin]], requiring that plugin and implementing a command of that plugin.
 +
 +This command is useful for...
 +
 +  * Representing data in DokuWiki separately from its formatting.
 +  * Applying repetitive formatting to each of multiple data items.
 +  * Generating rich HTML for inclusion in a DokuWiki page.
 +  * Expressing DokuWiki-maintained data in rich HTML.
 +
 +The command defines a kind of page called a //data page//. A data page is just a series of DokuWiki [[:wiki:syntax#lists|lists]] delimited by horizontal rules. Each list represents a record, and each item in a list represents a field of the record.
 +
 +A template command takes optional parameters, a template file name, and the name of a data page. Here are some example uses:
 +
 +<code>
 +  #template(news.php|health:news updates)#
 +  #template?category=health(news.php|news:records)#
 +  #template(mla.php|article references)#
 +  #template(calendar.php|calendar:events)#
 +  #template?from=2004-1-1&to=2005-1-1(calendar.php|calendar:events)#
 +  #template?_cache(calendar.php|calendar:events)#
 +</code>
 +
 +The parameters are handed to the template file, allowing for parametrized templates. The template file may produce either HTML or DokuWiki [[:wiki:syntax]] that is in turn translated to HTML --- which ever is easiest for the template writer.
 +
 +Here are two demo pages that are generated by this command:
 +
 +  * <del>[[http://www.spiderjoe.com/spiders/calendar|Spider Calendar]]</del>
 +  * <del>[[http://www.spiderjoe.com/spiders/oak-hill|Spiders of Oak Hill]] </del>
 +
 +===== Modification History =====
 +
 +  * 2005/08/30 --- Created. [[http://www.spiderjoe.com|Spider Joe]]
 +  * 2005/08/31 --- Was breaking RSS feed, which couldn't output headers. To fix, I now use PHP's built-in output buffer nesting. [[http://www.spiderjoe.com|Spider Joe]]
 +  * 2005/09/09 --- Added the ability to put the data set directly in the command. [[http://www.spiderjoe.com|Spider Joe]]
 +  * 2005/09/09 --- Fixed another problem with RSS. template() was not available. [[http://www.spiderjoe.com|Spider Joe]]
 +
 +===== Installation =====
 +
 +To install this command, first make sure you have a recent version of the [[plugin:command|Command Plugin]] installed. Then save the provided [[#source_template.php|source]] file with filename ''template.php'' in the following directory:
 +
 +<code>
 +/lib/plugins/command/ext/
 +</code>
 +
 +You now need to create a template file and a data file, and then you're ready to try the command.
 +
 +====== Syntax =====
 +
 +The Template command conforms to the [[plugin:command|Command Plugin]] syntax. In particular, it takes one of the following forms:
 +
 +  * ''%%#template(template.php|data page)#%%''
 +  * ''%%#template?_cache(template.php|data page)#%%''
 +  * ''%%#template?parameters(template.php|data page)#%%''
 +  * ''%%#template?_cache&parameters(template.php|data page)#%%''
 +  * ''%%#template(template.php|... Your data set goes here)#%%''
 +
 +As described in the [[plugin:command|Command Plugin]], the command name 'template' is not case sensitive, and the above syntax places the generated HTML outside of paragraphs, while ''%% %template()% %%'' syntax embeds the generated HTML in a paragraph (the current paragraph). The ''%'' notation is called //inline embedding// and the ''#'' notation is called //block embedding//.
 +
 +==== Command Name ====
 +
 +Each extension of the [[plugin:command|Command Plugin]] has a unique command name. This command takes the name **TEMPLATE**.
 +
 +==== Parameters ====
 +
 +The values that may follow the ''?'' in a [[plugin:command|Command Plugin]] command are called parameters. This command accepts optional parameters. Only one parameter affects the behavior of the command, independently of the template:
 +
 +  * ''_cache'' (optional): Cache the page that contains the command. When present, the containing pages won't reflect data page changes until it is resaved. When absent, the containing page is never cached, so that the page automatically remains accurate. The server does more work per page access when caching is off.
 +
 +All additional parameters are passed straight to the template file. This allows a template file to be designed so that each use of the template command can uniquely filter or format the data of a data page.
 +
 +==== Content ====
 +
 +The text that the user inserts between the opening ''('' and closing '')'' parentheses of a [[plugin:command|Command Plugin]] is called the //content//. For example, in ''%% %template(format.php|ns:data)% %%'', the content is ''%%format.php|ns:data%%''. The content of the template command must have one of the following two formats:
 +
 +<code>
 +  template_file|data_page
 +  template_file|... data_set
 +</code>
 +
 +  * ''template_file'' --- The name of the PHP template file. This file typically has extension ''.php''. The extension must be included. The command looks for the template file in the active ''lib/tpl/'' directory (e.g. ''lib/tpl/default/''); ''template_file'' is a path relative to this directory. The characters "''..''" may not be included in the path name.
 +  * ''data_page'' --- The name of the data page. This name must be namespace-qualified if the data page resides within a namespace.
 +  * ''data_set'' --- The data set to use. Instead of putting the data set in a separate page, you may put '%%...%%' into the command and follow it with the actual data set that would otherwise go in a separate data page.
 +
 +===== Data Page Format =====
 +
 +A data page is a page that represents a set of records. Each record is a DokuWiki [[:wiki:syntax#lists|list]], and each item of the list provides a field of the record. Multiple records are delimited with the horizontal rule, denoted in the DokuWiki [[:wiki:syntax]] by "''%%----%%''".
 +
 +Here is an example data page:
 +
 +<code>
 +Any text you put before the first list item of record is ignored. This is a good place to describe the data page or to describe the next record.
 +
 +  * date: 2005-7-31
 +  * category: DokuWiki
 +  * page: [[http://www.meganews.com?id=12345|DokuWiki has done it again!]]
 +  * abstract: The amazing **Andi Gohr** has produced a [[plugin:gallery|gallery plugin]] to die for.
 +
 +----
 +  * date: 2005-8-30
 +
 +  * category: Spiders
 +  * page: [[http://www.spiderjoe.com/spiders/oak-hill/mrs-featherlegged|Mrs. Fanged Featherlegged]]
 +  * abstract:
 +Of the 900 or so species of spiders living in Texas, only seven lack poison glands. One of these spiders raised a family beside the dog house in my back yard.
 +  * follow up:
 +
 +----
 +
 +Again, text you put before the first list item is ignored, so you can describe the record.
 +
 +  * date: 2000-1-1
 +  * #category: Warnings --- the # comments out a field
 +  * category: Catastrophies
 +  * page: [[http://www.meganews.com?id=666|Armageddon finally occurs]]
 +  * abstract:
 +
 +We'd been waiting for it for centuries and now it has finally happened. **Armageddon** has finally occurred.
 +
 +Read all about it from the comfort of your home, at your fancy multimedia computer.
 +
 +  * follow up: The world was reborn, minds were erased, and we were given another shot. Next Armageddon: Year 2100. Click [[http://runwithfear.com/go|here]] to run with fear.
 +----
 +Empty records are ignored.
 +</code>
 +
 +This example isn't exactly pretty, as it's meant to demonstrate the variety of formatting that the template command will accept.
 +
 +Each list item represents a field and has the following format:
 +
 +<code>
 +  * field_name: field_value
 +multi_para_value
 +</code>
 +
 +  * ''field_name'' --- The name of the field. It may contain any character other than the colon. If preceded by a ''#'', the field and its value is ignored, even if the value is given by a ''multi_para_value''.
 +  * ''field_value'' (optional) --- The value of the field, expressed in a single line. If neither a ''field_value'' nor a ''multi_para_value'' is provided, the field value is an empty string.
 +  * ''multi_para_value'' (optional) --- A long representation of the field value, allowing it to include multiple paragraphs. Generally, one should only provide either a ''field_value'' or a ''multi_para_value'', but not both.
 +
 +Text that appears before the first list item of a record is ignored and may be used to comment the page or the record. Note that DokuWiki needs a blank line before each horizontal rule. Records not containing any list items are ignored and are not handed to the template. This happens when two horizontal rules appear back-to-back or when one appears at the start or end of the file.
 +
 +Note that the ''field_value'' and ''multi_para_value'' representations need not be equivalent. In an HTML template, each paragraph of a ''multi_para_value'' is wrapped in <p> tags, while in a DokuWiki [[:wiki:syntax]] template, there are no <p> tags, but any blank lines present will be included.
 +
 +Whitespace preceding or trailing each ''field_value'' or ''multi_field_value'' is trimmed and so is not significant.
 +
 +===== Template Files ======
 +
 +A template file is a file that uses PHP to generate HTML or DokuWiki [[:wiki:syntax]] from a data set. The file is placed in the active ''lib/tpl/'' directory or in some subdirectory thereof. (The default active template directory is ''lib/tpl/default/''.)
 +
 +How a template file works can be summarized in a few points:
 +
 +  - Think of the file as a regular HTML or DokuWiki [[:wiki:syntax]] file that may contain embedded PHP. Everything outside of the PHP tags and all output echoed by PHP becomes part of the generated result.
 +  - The PHP in the file runs within an outer, invisible PHP function. All this means is that you must declare any globals you want to use.
 +  - The ''$TEMPLATECOMMAND_SOURCE'' variable is available to the PHP code. This variable contains an object from which the code gets its source data.
 +
 +''$TEMPLATECOMMAND_SOURCE'' contains an object of class ''TemplateCommandSource''. You need only be aware of three methods of this class:
 +
 +  * ''getParamHash()'' --- Returns an associative array of all the parameters that the user provided to the template command. The [[plugin:command|Command Plugin]] allows parameters to be assigned via an "''=''". When a parameter is so assigned, the value to the left of the "''=''" is a key of the array, and the value to the right is the value at that key. When a parameter is included without an "''=''", the parameter provided becomes the key and the value at that key is the empty string. For example, "''#template?1&1&2&a&b=&c=3&d=4&d=5(format.php|data)#''" produces array('1'=>'', '2'=>'', 'a'=>'', 'b'=>'', 'c'=>'3', 'd'=>'5').
 +  * ''getTextRecords()'' --- Returns an array of records, ordered according to their order of appearance within the data page. Each record is an associative array mapping the ''field_name'' to its ''field_value'' or ''multi_para_value''. The field values will be the raw text that appears within the data page, as seen when editing the data page; DokuWiki [[:wiki:syntax]] will not have been translated to HTML. Calling this method informs the template command that the template is generating DokuWiki [[:wiki:syntax]]. The command will subsequently translate it to HTML.
 +  * ''getHtmlRecords()'' --- Returns an array of records, ordered according to their order of appearance within the data page. Each record is an associative array mapping the ''field_name'' to its ''field_value'' or ''multi_para_value''. The field values will already have their DokuWiki [[:wiki:syntax]] translated to HTML. Calling this method informs the template command that the template is generating the HTML to be displayed.
 +
 +All field values are reported with preceding and trailing whitespace trimmed. Note that in records retrieved via ''getHtmlRecords()'', each paragraph of a ''multi_para_value'' field value will be wrapped in <p> tags, as we expect DokuWiki to do.
 +
 +===== Source (template.php) =====
 +
 +<file php template.php>
 +<?php
 +/**
 + * Template Command: Render a data set from a template.
 + *
 + * For a full description of this Command Plugin command, see:
 +   http://www.splitbrain.org/plugin:template
 + *
 + * (Thank you Esther Brunner for the include plugin, which
 + * showed me how to nab a DokuWiki-parsed page, and thank you
 + * Christopher Smith, who told me how to parse arbitrary text.)
 + *
 + * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 + * @author     Joe Lapp <http://www.spiderjoe.com>
 + *
 + * Modification History:
 + *
 + * 2005/08/30 - Created. JTL
 + * 2005/08/31 - Now uses ob nesting so RSS can write its headers. JTL
 + * 2005/09/09 - Added ability to include data set in command. JTL
 + * 2005/09/09 - template() was not available from within RSS. JTL
 + */
 +
 +define('TEMPLATECOMMAND_CONTENT_ERROR', '_INVALID_TEMPLATE_CONTENT_');
 +define('TEMPLATECOMMAND_DATA_NOT_FOUND', '_DATA_SET_NOT_FOUND_');
 +define('TEMPLATECOMMAND_TEMPLATE_NOT_FOUND', '_TEMPLATE_NOT_FOUND_');
 + 
 +class CommandPluginExtension_template extends CommandPluginExtension
 +{
 +    function getCachedData($embedding, $params, $paramHash, $content,
 +                             &$errorMessage) // STATIC
 +    {
 +        // Extract the template file name and data set ID.
 +
 +        $barPos = strpos($content, '|');
 +        if($barPos === false)
 +        {
 +            $errorMessage = TEMPLATECOMMAND_CONTENT_ERROR;
 +            return;
 +        }
 +        
 +        /* next lines work even if get empty strings */
 +        $templateName = trim(substr($content, 0, $barPos));
 +        $dataSet = trim(substr($content, $barPos + 1));
 +    
 +        if($templateName == '' || $dataSet == '')
 +        {
 +            $errorMessage = TEMPLATECOMMAND_CONTENT_ERROR;
 +            return;
 +        }
 +        $templateFN = CommandPluginExtension_template::template($templateName);
 +        if(strlen($dataSet) >= 3 && substr($dataSet, 0, 3) == '...')
 +        {
 +            $dataSetType = 'text';
 +            $dataSet = substr($dataSet, 3);
 +        }
 +        else
 +            $dataSetType = 'id';
 +        
 +        // Cache the page if caller allows it.
 +        
 +        if(isset($paramHash['_cache']))
 +        {
 +            $errorMessage = CommandPluginExtension_template::resolve(
 +                                $templateFN, $dataSetType, $dataSet);
 +            if($errorMessage)
 +                return;
 +            return CommandPluginExtension_template::generate(
 +                            $templateFN, $dataSetType, $dataSet, $paramHash);  
 +        }
 +        
 +        // Cache info needed to dynamically load page.
 +        
 +        return array($templateFN, $dataSetType, $dataSet, $paramHash);
 +    }
 +    
 +    function runCommand($embedding, $cachedData, &$renderer,
 +                          &$errorMessage) // STATIC
 +    {
 +        if(is_string($cachedData))
 +            return $cachedData;
 +            
 +        list($templateFN, $dataSetType, $dataSet, $paramHash) = $cachedData;
 +
 +        $errorMessage = CommandPluginExtension_template::resolve(
 +                            $templateFN, $dataSetType, $dataSet);
 +        if($errorMessage)
 +            return;
 +
 +        $renderer->info['cache'] = false;
 +        return CommandPluginExtension_template::generate(
 +                        $templateFN, $dataSetType, $dataSet, $paramHash);  
 +    }
 +    
 +    function resolve($templateFN, $dataSetType, &$dataSet) // STATIC
 +    {
 +        global $ID;
 +    
 +        if(strpos($templateFN, '..') !== false ||
 +                !@file_exists($templateFN)) // PHP caches the results
 +            return TEMPLATECOMMAND_TEMPLATE_NOT_FOUND;
 +    
 +        if($dataSetType == 'id')
 +        {
 +            $exists = false;
 +            resolve_pageid(getNS($ID), $dataSet, $exists);
 +            if(!$exists || auth_quickaclcheck($dataSet) < AUTH_READ)
 +                return TEMPLATECOMMAND_DATA_NOT_FOUND;
 +        }
 +        return null;
 +    }
 +    
 +    function generate($templateFN, $dataSetType, $dataSet, $paramHash) // STATIC
 +    {
 +        // Generate HTML or text from the template.
 +
 +        $source = new TemplateCommandSource($templateFN, $dataSetType,
 +                                             $dataSet, $paramHash);
 +        ob_start();
 +        CommandPluginExtension_template::runTemplate($source);
 +        $outString = ob_get_contents();
 +        ob_end_clean();
 +        
 +        // If the template generated text, translate into HTML.
 +        
 +        if(!$source->isHTML)
 +        {
 +            $instructs = p_get_instructions($outString);
 +            $info = array();
 +            $outString = p_render('xhtml', $instructs, $info);
 +        }
 +        
 +        return $outString; // return generated HTML
 +    }
 +    
 +    function runTemplate(&$TEMPLATECOMMAND_SOURCE)
 +    {
 +        // Isolate template in its own function because it has access to
 +        // the function variables. Template writes to standard out.
 +        
 +        include($TEMPLATECOMMAND_SOURCE->templateFN);
 +    }
 +
 +    /**
 +     * This is a duplicate of its namesake in template.php, since the
 +     * namesake is not available in an RSS feed.
 +     *
 +     * @author Andreas Gohr <andi@splitbrain.org>
 +     */
 +    function template($tpl){
 +      global $conf;
 +
 +      if(@is_readable(DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl))
 +        return DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl;
 +
 +      return DOKU_INC.'lib/tpl/default/'.$tpl;
 +    }
 +}
 +
 +/******************************************************************************
 +TemplateCommandSource - Source of data for PHP implementing template
 +******************************************************************************/
 +
 +class TemplateCommandSource
 +{
 +    //// FRIEND VARIABLES /////////////////////////////////////////////////////
 +
 +    var $isHTML = true;
 +    var $templateFN;
 +
 +    //// PRIVATE VARIABLES ////////////////////////////////////////////////////
 +    
 +    var $dataSetText = null;
 +    var $dataSetFN = null;
 +    var $paramHash;
 +    
 +    var $textRecords = null;
 +    var $htmlRecords = null;
 +
 +    //// PUBLIC METHODS ///////////////////////////////////////////////////////
 +
 +    function getParamHash()
 +    {
 +        return $this->paramHash;
 +    }
 +
 +    function getTextRecords()
 +    {
 +        $this->isHTML = false;
 +        if($this->textRecords != null)
 +            return $this->textRecords;
 +        
 +        if($this->dataSetText != null)
 +            $outline = $this->dataSetText;
 +        else
 +        {
 +            $outline = '';
 +            $outline = @file_get_contents($this->dataSetFN);
 +        }
 +        
 +        $outlineParser = new TextOutlineRecordParser($outline);
 +        $this->textRecords = $outlineParser->getRecords();
 +        return $this->textRecords;        
 +    }
 +    
 +    function getHtmlRecords()
 +    {
 +        $this->isHTML = true;
 +        if($this->htmlRecords != null)
 +            return $this->htmlRecords;
 +
 +        if($this->dataSetText != null)
 +            $instructs = p_get_instructions($this->dataSetText);
 +        else
 +            $instructs = p_cached_instructions($this->dataSetFN);
 +        
 +        $info = array();
 +        $outline = p_render('xhtml', $instructs, $info);
 +
 +        $outlineParser = new HTMLOutlineRecordParser($outline);
 +        $this->htmlRecords = $outlineParser->getRecords();
 +        return $this->htmlRecords;        
 +    }
 +
 +    //// FRIEND METHODS ///////////////////////////////////////////////////////
 +
 +    function TemplateCommandSource($templateFN, $dataSetType, $dataSet,
 +                                    $paramHash)
 +    {
 +        $this->templateFN = $templateFN;
 +        if($dataSetType == 'id')
 +            $this->dataSetFN = wikiFN($dataSet);
 +        else
 +            $this->dataSetText = $dataSet;
 +        $this->paramHash = $paramHash;
 +    }
 +}
 +
 +/******************************************************************************
 +OutlineRecordParser - Base class for outline record parsers
 +******************************************************************************/
 +
 +class OutlineRecordParser
 +{
 +    //// PROTECTED VARIABLES //////////////////////////////////////////////////
 +
 +    var $records = array(); // list of records expressed as associative arrays
 +
 +    //// PUBLIC METHODS ///////////////////////////////////////////////////////
 +
 +    function getRecords()
 +    {
 +        return $this->records;
 +    }
 +
 +    //// PROTECTED METHODS ////////////////////////////////////////////////////
 +
 +    function parseRecord($fieldSplits)
 +    {
 +        $record = array();
 +
 +        // Iterate over the fields. Whatever precedes the first line item
 +        // of a record is ignored and so may be used for comments.
 +    
 +        for($i = 1; $i < sizeof($fieldSplits); ++$i)
 +            $this->parseField($record, trim($fieldSplits[$i]));
 +        
 +        if(!empty($record))
 +            array_push($this->records, $record);
 +    }
 +    
 +    function parseLineItem($lineItem, &$fieldName, &$fieldValue)
 +    {
 +        $colonPos = strpos($lineItem, ':');
 +        if($colonPos === false)
 +        {
 +            $fieldName = trim($lineItem);
 +            $fieldValue = '';
 +        }
 +        else
 +        {
 +            $fieldName = trim(substr($lineItem, 0, $colonPos));
 +            // next line works even if nothing follows colon
 +            $fieldValue = trim(substr($lineItem, $colonPos + 1));
 +        }
 +    }
 +}
 +
 +/******************************************************************************
 +TextOutlineRecordParser - Parses wiki text for records expressed in outlines
 +******************************************************************************/
 +
 +class TextOutlineRecordParser extends OutlineRecordParser
 +{
 +    //// PUBLIC METHODS ///////////////////////////////////////////////////////
 +
 +    function TextOutlineRecordParser($outline)
 +    {
 +        $outline = "\n".$outline; // makes the pregs easier
 +    
 +        // wiki horizontal rules delimit records
 +        $recordSplits = preg_split('/[\n\r]+----+/', $outline);
 +        foreach($recordSplits as $recordSplit)
 +        {
 +            $fieldSplits = preg_split('/[\n\r]+  +\*/', $recordSplit);
 +            $this->parseRecord($fieldSplits);
 +        }
 +    }
 +
 +    //// PROTECTED METHODS ////////////////////////////////////////////////////
 +
 +    function parseField(&$record, $fieldSplit)
 +    {
 +        // Extract the line item.
 +    
 +        $endLineItem = strcspn($fieldSplit, "\n\r");
 +        
 +        if($endLineItem === false)
 +            $lineItem = $fieldSplit;
 +        else
 +            $lineItem = substr($fieldSplit, 0, $endLineItem);
 +            
 +        // Skip over commented out fields.
 +        
 +        if($lineItem{0} == '#')
 +            return; // commented out field
 +            
 +        // Extract the field name and the line-item value.
 +        
 +        $fieldName = null;
 +        $fieldValue = null;
 +        $this->parseLineItem($lineItem, $fieldName, $fieldValue);
 +
 +        // Extract the field's multi-line value, if any.
 +
 +        if($endLineItem !== false)
 +        {
 +            $multiline = trim(substr($fieldSplit, $endLineItem));
 +            if($multiline != '')
 +                $fieldValue .= $multiline;
 +        }
 +        
 +        // Record the extracted field.
 +        
 +        $record[$fieldName] = $fieldValue;
 +    }
 +}
 +
 +/******************************************************************************
 +HTMLOutlineRecordParser - Parses HTML for records expressed in outlines
 +******************************************************************************/
 +
 +class HTMLOutlineRecordParser extends OutlineRecordParser
 +{
 +    //// PUBLIC METHODS ///////////////////////////////////////////////////////
 +
 +    function HTMLOutlineRecordParser($outline)
 +    {
 +        // remove <ul>s and <ol>s
 +        $outline = preg_replace('/<[ou]l(\s.*?)?>/', '', $outline);
 +    
 +        // <hr/>s delimit records
 +        $recordSplits = preg_split('/<hr(\/|\s.*?)?>/', $outline);
 +        foreach($recordSplits as $recordSplit)
 +        {
 +            $fieldSplits = preg_split('/<li(\/|\s.*?)?>/', $recordSplit);
 +            $this->parseRecord($fieldSplits);
 +        }
 +    }
 +
 +    //// PROTECTED METHODS ////////////////////////////////////////////////////
 +
 +
 +
 +    function parseField(&$record, $fieldSplit)
 +    {
 +        // Extract the line item.
 +    
 +        $endLineItem = strpos($fieldSplit, '</li>');
 +        if($endLineItem === false)
 +            return; // bad HTML
 +        $lineItem = substr($fieldSplit, 0, $endLineItem);
 +            
 +        $firstChar = $lineItem{0};
 +        if($firstChar == '<')
 +        {
 +            $newLeft = strpos($lineItem, '>') + 1;
 +            $newLength = strrpos($lineItem, '<') - $newLeft;
 +            $lineItem = ltrim(substr($lineItem, $newLeft, $newLength));
 +            $firstChar = $lineItem{0};
 +        }
 +        
 +        // Skip over commented out fields.
 +        
 +        if($firstChar == '#')
 +            return; // commented out field
 +            
 +        // Extract the field name and the line-item value.
 +        
 +        $fieldName = null;
 +        $fieldValue = null;
 +        $this->parseLineItem($lineItem, $fieldName, $fieldValue);
 +
 +        // Extract the field's multi-line value, if any.
 +        
 +        $endOutline = strpos($fieldSplit, '</ol>');
 +        if($endOutline === false)
 +            $endOutline = strpos($fieldSplit, '</ul>');
 +            
 +        if($endOutline !== false)
 +        {
 +            // next line works even if nothing follows </ol> or </ul>
 +            $multiline = trim(substr($fieldSplit, $endOutline + 5));
 +            if($multiline != '')
 +                $fieldValue .= $multiline;
 +        }
 +        
 +        // Record the extracted field.
 +        
 +        $record[$fieldName] = $fieldValue;
 +    }
 +}
 +?>
 +</file>
 +
 +===== Examples =====
 +
 +Bear in mind that, although the following examples generate HTML, the template file may instead generate DokuWiki [[:wiki:syntax]] by calling ''$TEMPLATECOMMAND_SOURCE->getTextRecords()'' instead of ''$TEMPLATECOMMAND_SOURCE->getHtmlRecords()''. I just don't have a live example to show you. You might want to generate DokuWiki syntax if it's easier than generating the HTML, as it usually will be. Also, these examples used to use a separate data page. I have since moved the data directly into the command using the new '%%...%%' syntax.
 + 
 +
 +  * The [[http://www.spiderjoe.com/spiders/calendar|Spider Calendar]] page is generated via  [[http://www.spiderjoe.com/spiders/calendar?do=edit|this command]] using the following template:
 +
 +<code html><div class='content_header'>Upcoming Spider Events</div>
 +
 +<div class="fix_IE6">
 +<table width="100%" border="0" cellpadding="0" cellspacing="0" >
 +<?php
 +$records = $TEMPLATECOMMAND_SOURCE->getHtmlRecords();
 +
 +foreach($records as $record)
 +{
 +    if(isset($record['month']))
 +    {
 +?>
 +<tr>
 +<td class='month_row' colspan='6'><div class='event_month'><?php echo $record['month']; ?></div></td>
 +<tr>
 +<?php
 +    }
 +    else
 +    {
 +?>
 +<tr class='event_header'>
 +<td width='1%'>&nbsp;</td>
 +<td class="left_field" width='29%'><?php echo $record['date']; ?></td>
 +<td class="left_field" width='24%'><?php echo $record['type']; ?></td>
 +<td class="left_field" width='16%'><?php echo $record['time']; ?></td>
 +<td width='29%'><?php echo $record['city']; ?></td>
 +<td width='1%'>&nbsp;</td>
 +</tr>
 +<tr>
 +<td class='event_details' colspan='6'><?php if(isset($record['title'])) { ?>
 +&quot;<span class='event_title'><?php echo $record['title']; ?></span>,&quot;
 +<?php } echo $record['details']; ?></td>
 +</tr>
 +<?php
 +    }
 +}
 +?>
 +</table>
 +</div><!--fix_IE6--></code>
 +
 +  * The [[http://www.spiderjoe.com/spiders/calendar|Oak Hill]] page is generated via a data set included in a template command [[http://www.spiderjoe.com/spiders/oak-hill?do=edit|on this page]] using the following template:
 +
 +<code html><?php
 +global $conf; // template is executed from within a function
 +
 +$records = $TEMPLATECOMMAND_SOURCE->getHtmlRecords();
 +
 +$side = 'left';
 +foreach($records as $record)
 +{
 +    $pageURL = $conf['basedir'].idfilter(cleanID($record['page']));
 +    $title = $record['title'];
 +
 +    echo '<div class="abstract_'.$side.'"><p>';
 +
 +    if(isset($record['image']))
 +    {
 +        $imageID = idfilter(cleanID($record['image']));
 +        $imageURL = $conf['basedir'].'_media/'.$imageID.'?cache=cache';
 +        $imageWidth = '';
 +        if(isset($record['image-width']))
 +        {
 +            $imageWidth = $record['image-width'];
 +            $imageURL .= "&amp;w=$imageWidth&amp;h=";
 +        }
 +
 +        echo "<a href='$pageURL' class='media'><img src='$imageURL' class='media$side'".
 +             " title='$title' alt='$title' width='$imageWidth'></a>";
 +    }
 +
 +    echo "<strong><a href='$pageURL' class='wikilink1'".
 +         " onclick='return svchk()' onkeypress='return svchk()'>";
 +    echo $title;
 +    echo '</a></strong>. ';
 +    echo $record['abstract'];
 +    echo "</div>\n\n";
 +    
 +    $side = ($side == 'left') ? 'right' : 'left';
 +}
 +?>
 +</code>
 +
 +> Note that the JavaScript function "svchk()" no longer exists (and is now unnecessary) in DokuWiki, and does cause JavaScript errors, so references should be removed.
 +>-- [[todd@rollerorgans.com]] 2007-02-26
 +
 +===== Discussion =====
 +
 +  * The template command allows the user to name any file in the DokuWiki ''%%lib/tpl/%%'' templates directory. The command specifically does not allow the filename to include '%%..%%', but there are no other constraints. Is there a potential security problem I need to handle? Thanks!  --- [[http://www.spiderjoe.com|Spider Joe]]
 +
 +  * The example links (http://www.spiderjoe.com/spiders/calendar) do not work. -- [[wonko@wonkology.org|Wonko]] 2006-07-01
 +
 +  * <del>DokuWiki syntax is not processed if I simple make the template ''echo'' it. Please give an example. Thanks!</del>. Ok, I read more carefully and found that it depended in which function was called to get the records. I modified the page a bit to make it more explicitly to those of us who just skim through the instructions :D. 2006-09-05
 +
 +  * First, thanks for this plugin :) . I encountered some problems using this plugin with the [[plugin:tag|tag plugin]]. Details : i used the "getTextRecords" function to generate a DokuWiki code. Within my php code when i echo the following statement : <code>"{{tag>foo bar}}"</code> statement (cf tag plugin page for more info about it). The render is correct (i.e. the tags are displayed under an horizontal line as expected) but the problem is that the page is not associated with the tags. For example when I click on the tag the page are not listed as a tagged page, even after a rebuild index of tags (via tag plugin manager menu)... any idea? How could i generate dynamic tags?
 +
 +===PHP error===
 +
 +This plugin seems to almost work for my DW2009-02-14 with default template. However when I try to insert template command <code>%template(wpis.php|:datapage)%</code> and save a page for the first time with the most basic template I wrote <code><?php
 +$records = $TEMPLATECOMMAND_SOURCE->getTextRecords();
 +foreach($records as $record)
 +{
 +echo $record['n'];
 +};
 +?></code>I get a PHP error
 +<code>Warning: Cannot modify header information - headers already sent by 
 +(output started at /lib/plugins/command/ext/template.php:424)
 + in /inc/common.php on line 1476</code> Next saves of the page cause no error.
 +
 +Furthermore, I can not arrive to write a date set correctly so as not to receive  _ _DATASET_ _NOT_ _FOUND. Could you provide any example of a command with a data set, not data page?
 +
 +---// LukeWestwalker 2009/06/21//

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki