====== Templater Plugin ======
---- plugin ----
description: Allow wikipages to become templates for inclusion into other wikipages, like wikipedia
author : Jonathan Arkell
email : jonnay@jonnay.net
type : syntax
lastupdate : 2005-10-24
compatible :
depends :
conflicts :
similar : template, include
tags : template, include, variable, experimental
----
===== Warning =====
This plugin is [[experimental]], and its behavior subject to change in the future. It may also be folded into the include plugin
===== Description =====
The Templater plugin is an extension of the [[plugin:include]] plugin. Like the include plugin, it allows you to embed one wikipage inside of another. Unlike the include plugin, the Templater also allows you to pass the included wikipage substitution strings to change the output of the included wikipage.
Just like the include plugin you use it like this:
{{template>pagename}}
You may as well include pages from a different namespace: ''%%{{template>namespace:pagename}}%%''. The [[namespaces]] shortcuts do also work: ''%%{{template>:pagename}}%%'' (top namespace) or ''%%{{template>.namespace:pagename}}%%'' (subnamespace).
Optionally you can limit the included page to a specific section (including its subsections):
{{template>pagename#sectionname}}
The real power of this plugin comes in to play when you want to use the same general layout for an element inside of a wikipage, but with different pieces of data. You create a new template page, and instead of putting in the actual values, you give each value a name, and enclose them in at-signs like this:
=== This is the wikipage 'TemplateWikiPage' ===
== @subtitle@ ==
My name is @name@. I am a @value@.
Then on a page where you want to include this template, but with string substitutions, you would do this:
{{template>TemplateWikiPage|subtitle=Foo|name=Jonnay|value=Crazy Guy}}
Which outputs this:
=== This is the wikipage 'TemplateWikiPage' ===
== Foo ==
My name is Jonnay. I am a Crazy Guy.
===== Plugin =====
To install, put the following PHP file in ''/lib/plugins/templater/syntax.php''. Or download from (or point your plugin manager to) here: [[http://wiki.jonnay.net/_media/bunny/templater.tar?cache=nocache]] FIXME
page}} for "page" in same namespace
* {{template>:page}} for "page" in top namespace
* {{template>namespace:page}} for "page" in namespace "namespace"
* {{template>.namespace:page}} for "page" in subnamespace "namespace"
* {{template>page#section}} for a section of "page"
*
* Replacers are handled in a simple key/value pair method.
* {{template>page|key=val|key2=val|key3=val}}
*
* Templates are wiki pages, with replacers being delimiteded like
* {key1} {key2} {key3}
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Jonathan arkell
===== Style =====
The included page is set into a ''
.templater {
padding: 0.5em;
}
===== Changes =====
* 2005-10-26 **v0.2**
* Changed the subsitution delimiters from {} to @
* Perform substitution on parsing rather then on output
* When the template does not exist show a link to create the template
* 2005-10-25 **v0.1**
* First Version
===== To Do =====
* Better error handling in _massageReplacers
* Template caching of parser instructions.
* Make the code a little clearer
* Use > in template arguments to point to a wikipage contaning a dataset.
* Default template namespace.
* Escaping of vertical bar.
===== Discussion =====
==== Errors ====
*Plugin manager can't seem to find the plugin with the URL given. It may be a problem with the .tar extension and the gz compression.
*To use a Template with multible linse e.g.:
{{template>TemplateWikiPage
|subtitle=Foo
|name=Jonnay}}
is only possible in this form:
{{template>TemplateWikiPage
|subtitle=Foo|
|name=Jonnay| }}
Bug or feature? .)
----
=== Several instances of the same template in one wiki page doesn't work ===
It would be fine, to call with this plugin the same template_page several times inside a wiki page.
I want to create a page with dynamically created images from rrdtool.
For this i use a cgi-script with many options, which i'd like to pack in a template-page.
My page looks like this:
====== Performance data Production Line ======
++++ Load average |
__**SAP DB & CI - Cluster**__
{{template>.template_performance|host=host1|service=la|graph=daily}}
{{template>.template_performance|host=host2|service=la|graph=daily}}
__**Dev system**__
{{template>.template_performance|host=host3|service=la|graph=daily}}
++++
and my template page "template_performance" (in the same directory):
{{http://admin-host/hobbit-cgi/hobbitgraph.sh?host=@host@&service=@service@&graph_height=120&graph_width=300&action=view&graph=@graph@&.png?nocache&nolink}}
On the resulting page the first instance of templater is correct.
But all other result in "Template not found. [Click here to create it]".
The usage of different template pages inside one wiki page works correct.
--- [[uwe.kirbach@arcor.de|Uwe Kirbach]] 2006-05-09
Hello Jonathan,
please could you look into this problem, because i'm not a php programmer to solve it. \\
This feature is very important for me: :!: **Several includes of the same template page inside one wiki page.**
--- [[uwe.kirbach@arcor.de|Uwe Kirbach]] 2006-09-02
== Solution ==
To fix this, you just need to comment the following, which is around the 100th line.
if (in_array($wikipage[0], $filechain)) return false;
It seems that the include template especifically avoided including the same page multiple
times. This might have to do with a template including itself, or other cyclic inclusion,
so watch out when you try to include a template inside another, or you might end with
an infinite loop.
--- [[hugo.peixoto@gmail.com|Hugo Peixoto]] 2007-02-24
----
==== Use with inline folding plugin ====
This text copied wholesale from the [[plugin:include]] plugin. It **should** work the same.
Use the [[folded|block type of the folded text plugin]], if you want to have another page availaible but hidden until the user clicks the inline folding icon. The syntax would be such as:
++++folder link title| {{templater>page to include}} ++++
==== Wikitext inside of template values ====
Wikitext can now be used inside of template values.
==== Suggestions, Questions, Commentary ====
Just a question - how is this plugin actually different from the older included plugin? Is there any reason to have both installed?
> It's not. It is built upon the older include plugin, but allows you to do text substitution with the included wikipage. //[[jonnay@jonnay.net|Jonathan Arkell]] 2005-10-25 19:43//
----
Very neat plugin!
A few comments.
* Isn't it a bit extreme to "die" if there is a problem with your string substitution? Wiki pages are usually able to be edited by anyone - a graceful fail with or without a message might be nicer.
* It would be a good idea to filter the replacement through $renderer->_xmlEntities() (htmlspecialchars()) as part of the assignment, OR,
* Carry out the replacement before passing the included page to the parser, you would automatically allow wiki markup in your replacements and also you wouldn't need to worry about filtering out special characters, the parser would do that for you.
--- //[[chris@jalakai.co.uk|Christopher Smith]] 2005-10-25 10:42//
> Thanks for the comments. I'll implement those suggestions in the next version --- //[[jonnay@jonnay.net|Jonathan Arkell]] 2005-10-25 19:43//
----
Great! This was a long standing feature request for the [[include]] plugin, and if my day had 28 hours I would have done it already. What do you think, should we re-combine these plugins? -- I tend to say yes because the functionality of the include plugin now is a subset of your new plugin. A darcs repository for the include plugin would be a good idea as well, so others can contribute more easily.
On a side note: I would have preferred the @ as BEGIN_ and END_REPLACE_DELIMITER to reach a higher coherence with the replacement patterns for [[config:signature|signatures]] and [[namespace_templates]].
--- //[[esther@kaffeehaus.ch|Esther Brunner]] 2005-10-25 11:11//
> I am totally willing to re-combine these plugins. This is really my first foray into hacking dokuwiki, so I am not sure what is involved in setting up a darcs repository. Also, I have no problem with having @ as the BEGIN/END_REPLACE_DELIMITER. Especially if it gives the overall codebase a higher coherence. --- //[[jonnay@jonnay.net|Jonathan Arkell]] 2005-10-25 19:46//
----
Looking at the way variables are specified now makes me think they'd better be placed into some other file instead of being literally specified every time. Something like ''%%{{templater>WikiTemplatePage@WikiDataPage}}%%''. This will let you conveniently use the same data with different templates.
And if you allow using macros in data page name - it will be even more powerful. :-) E.g. you could put user data (or whatever) as 'name=value' pairs to some data file and render it according to common template with ''%%{{templater>UserProfileTemplate@users:@USER@:profile}}%%'' call.
This will make it similar to [[plugin:template|command/template]] plugin but does not require writing PHP code for simple substitution templates. :-)
--- //[[2sabio@gmail.com|Dmitry Cherniachenko]] 2005-10-25 13:18//
> This is a really interesting idea, but a bit beyond the scope of what I had in mind for this plugin. This was built so that you can use the same presentation to layout different data, but it sounds like you're talking about using different presentations to layout the same data. How do you feel about a syntax like ''%%{{templater>UserProfileTemplate|>namespace:page#section}}%%''? We'd use the > to point to a page that contains the key=val pairs. The overall idea of this plugin is to move away from the server admin having to deal with textfiles on the machine, and move all the template administration to competent WikiGnomes. --- //[[jonnay@jonnay.net|Jonathan Arkell]] 2005-10-25 19:55//
----
This is obviously a great plugin. BUT I need some functionnalities, so I write a little bit about it :-) First, it could be great if we could put the character | as a part of a parameter value.
{{template>templatePage|param=^RowName\|Text\|Other Text}}
In this example, I make a table in DokuWiki syntax, escaping the pipe character by \. Currently (see $replacers = explode('|', $match); line 87), it is impossible to put | as a value, but preg_split could do it greatly and easily ;-)
After this first thing, I was wondering if it is possible to create template with optionnal arguments. Or maybe just not display @param@ if param is not provided. I didn't think about it deeper, so I am not sure of what could be implemented or not.
Conclusion : good work, the major part is done :-) Just 2 or 3 lines and it would be perfect --- Adrien CLERC
> I'll make the vertical bars escapeable in the next version. As for empy params: %%{{template>templatePage|blankParam=}}%% works just fine.
----
This could be very usufull? Unfortunately it failed on my first attempt to use it
{{template>TemplaterWhois|name=Nadim Khemir|mail=NKhemir@zicorp.com|image=nadim.png}}
[[NKhemir@zicorp.com]] 5th of April 2006
----
===Dynamic Templating?===
Great plugin! Is there a way to have it handle simple logic within the template itself? (Major Edit - I know know how to ask the question) - is there any way to include parser functions in a template?
----
=== Multiple copy of the same page? ===
Hello, since this version of templater is built upon an earlier version of [[include]], it seems that the plugin won't allow more than one copy of the same page to be loaded, i.e. it's impossible to put a few templates in a page, make them sections and to include them all in the same page, since the plugin shows that it can't find templates from other sections. Can someone merge this plugin to be based on newer [[include]] plugin? --- //[[Robertus0617@gmail.com|Roberto Ciang]] 2006-12-15 07:05//
If a page can only be include once, then it could be a really big limitation of this plugin, because people might need to insert the same message more than once in the page. --- //[[Robertus0617@gmail.com|Roberto Ciang]] 2006-12-15 07:17//
----
=== Templater keeping unneeded whitespace/newlines in macros ===
I found a problem with the plugin.- When using a templater call like this
{{template>my_template
|field1=foo
|field2=bar
|field3=baz}}
the templater plugin will also save the trailing newlines into field1, field2 and field3. This leads to problems when trying to insert these variables into an table. E.g. the following code:
| What: | @field1@ |
| When: | @field2@ |
is transformed into
| What: | foo
|
| When: | bar
|
which of course is not rendered correctly.
Fix: In the function _massageReplacers (i wonder if the function shouldn't be named messageReplacers?) change the two lines to $r['vals'] = $v; with $r['vals'] = trim($v);
----
=== Data entry and handling suggestions. ===
I very much needed this plugin, thanks. I think the data entry needs to be handled much easier than it currently is. Maybe something similar to the [[plugin:template|template plugin]] datafiles which uses a normal dw list of name:value pairs and is much easier to write. The template plugin allows the data to be culled from a data page or inline in the arguments. Also the template plugin data files support mutiple records in one file, if would be very nice to see a module mode where it can loop the data set through the template for each one or for a specific field match.Oh that would also allow for entry of more markup that cant be normally added in {} --ShawnA
===== Feature Enhancement - Optional Substitution =====
key =value a trim might make that doable.
Also if you fail to declare or choose not to a enter a variable then the template still shows the @variable@ string. It would be nice if it was removed or used an a optional **default** var eg. "N/A"," - ".{{tempate>page|DEFAULT_STR=**N/A**|}}
Any undefined variables will now show **N/A** for that template render.
**file:** /lib/plugins/templater/syntax.php **function:** render()
// Get the raw file, and parse it into its instructions. This could be cached... maybe.
$rawFile = io_readfile($file);
$rawFile = str_replace($data[1]['keys'], $data[1]['vals'], $rawFile);
+ // ShawnA modify - replace unmatched substitutions with "" or use DEFAULT_STR from data arguments if exists.
+
+ $left_overs = '/'.BEGIN_REPLACE_DELIMITER.'.*'.END_REPLACE_DELIMITER.'/';
+
+ $def_key=array_search(BEGIN_REPLACE_DELIMITER."DEFAULT_STR".END_REPLACE_DELIMITER,$data[1]['keys']);
+ if($def_key){ $DEFAULT_STR = $data[1]['vals'][$def_key];}
+ else $DEFAULT_STR = "";
+
+ $rawFile = preg_replace($left_overs,$DEFAULT_STR,$rawFile);
+
+ // end modify
$instr = p_get_instructions($rawFile);
// --ShawnA//
===== Feature Enhancement - More forgiving syntax =====
:!: I failed to consider spaces are used in formatting in table alignment and such. So this is probably not a good idea unless you adda trim to the $v as well.
Variable key:value pairs can be assigned as such ''key=var'' or ''key= var''.
**Problem:** Using ''key = var'' will fail. I prefer my operators and assignments be spaced for easier radablility and this makes it forgivable if someone does so.
In the messageReplacers function add a **trim()** around the $k variable in the 2 locations like below.
**file:** /lib/plugins/templater/syntax.php **function:** messageReplacers()
Before:
BEGIN_REPLACE_DELIMITER.$k.END_REPLACE_DELIMITER;
After:
BEGIN_REPLACE_DELIMITER.trim($k).END_REPLACE_DELIMITER;
// --ShawnA//
> The messageReplacers function is misspelled in the php code, so to perform the change listed above, search for massageReplacers. --- Carl M
It would be nice to be able to include pictures in the page using a template. This seems to be a problem as they use {{}}. A possible way to fix this would be using some kind of replacement for this (e.g.