%META:TOPICINFO{author="PeterThoeny" date="1072855797" format="1.0" version="1.21"}%
%META:TOPICPARENT{name="WebHome"}%
%TOC%
%STARTINCLUDE%
---# TWiki Templates

_Definition of the templates used to render all HTML pages displayed in TWiki_ 

---++ Overview

The new modular template system offers flexible, easy control over the layout of all TWiki pages. The master template approach groups parts that are shared by several templates - like headers and footers - in a common file. Special variables allow individual layouts to include parts from a master template - variables are mixed with regular HTML markup for template-specific content. Templates are used to define [[#HtmlTemplates][page layout]], and also to supply [[#TemplateTopics][default content]] for new pages.

---++ Major changes from the previous template system

Where the old templates were each complete HTML documents, the new templates are defined using variables to include template parts from a master file. You can now change one instance of a common element to update all occurrences; previously, every affected template had to be updated. This simplifies the conversion of templates into XHTML format, and provides a more versatile solution for templates and for TWikiSkins. The new system:

	* separates a set of common template parts into a base template that is included by all of the related templates;  
	* defines common variables, like a standard separator (ex: "|"), in the base template; 
	* defines variable text in the individual templates and passes it back to the base template.

#TemplateVariables
---++ How Template Variables Work

	* Special template directives (or preprocessor commands) are embedded in normal templates.
	* All template preprocessing is done in =&TWiki::Store::readTemplate()= so that the caller simply gets an expanded template file (the same as before).
	* Directives are of the form ==%<nop>TMPL:&lt;key&gt;%== and ==%<nop>TMPL:&lt;key&gt;{"attr"}%==.
	* Directives:
		* ==%<nop>TMPL:INCLUDE{"file"}%==: Includes a template file. The template directory of the current web is searched first, then the templates root (=twiki/templates=).
		* ==%<nop>TMPL:DEF{"var"}%==: Define a variable. Text between this and the END directive is not returned, but put into a hash for later use.
		* ==%<nop>TMPL:END%==: Ends variable definition.
		* ==%<nop>TMPL:P{"var"}%==: Prints a previously defined variable.
	* Variables live in a global name space: there is no parameter passing.
	* Two-pass processing lets you use a variable before or after declaring it.
	* Templates and TWikiSkins work transparently and interchangeably. For example, you can create a skin that overloads only the =twiki.tmpl= master template, like =twiki.print.tmpl=, that redefines the header and footer.
	* %H% Use of template directives is optional: templates work without them.
	* %X% *NOTE:* Template directives work only for templates: they do not get processed in topic text.

---++ Types of Template

There are three types of template:

	* *Master Template*: Stores common parts; included by other templates
	* *HTML Page Templates*: Defines the layout of %WIKITOOLNAME% pages
	* *Template Topics*: Defines default text when you create a new topic

---+++ Master Templates

Common parts, appearing in two or more templates, can be defined in a master template and then shared by others: ==twiki.tmpl== is the default master template.
<blockquote>
| *Template variable:* | *Defines:* |
| %<nop>TMPL:DEF{"sep"}% | "&#124;" separator |
| %<nop>TMPL:DEF{"htmldoctype"}% | Start of all HTML pages |
| %<nop>TMPL:DEF{"standardheader"}% | Standard header (ex: view, index, search)  |
| %<nop>TMPL:DEF{"simpleheader"}% | Simple header with reduced links (ex: edit, attach, oops) |
| %<nop>TMPL:DEF{"standardfooter"}% | Footer, excluding revision and copyright parts |
| %<nop>TMPL:DEF{"oops"}% | Skeleton of oops dialog |
</blockquote>

#HtmlTemplates
---+++ HTML Page Templates

%WIKITOOLNAME% uses HTML template files for all actions, like topic view, edit, and preview. This allows you to change the look and feel of all pages by editing just a few template files.

Templates are in the ==twiki/templates== directory. As an example, ==twiki/templates/view.tmpl== is the template file for the ==twiki/bin/view== script. Templates can be overloaded by individual webs. The following search order applies:

	1. ==twiki/templates/$webName/$scriptName.tmpl==
	2. ==twiki/templates/$scriptName.tmpl==
		* =$webName= is the name of the web (ex: =Main=)
		* =$scriptName= is the script (ex: =view=).

%H% *NOTE:* TWikiSkins can be defined to overload the standard templates.

Special variables are used in templates, especially in =view=, to display [[TWikiMetaData#MetaDataRendering][meta data]].

#TemplateTopics
---+++ Template Topics

Template topics define the default text for new topics. There are three types of template topic:
<blockquote>
| *Topic Name:* | *What it is:* |
| WebTopicViewTemplate | Error page shown when you try to view a nonexistent topic |
| WebTopicNonWikiTemplate | Alert page shown when you try to view a nonexistent topic with a non-WikiName |
| WebTopicEditTemplate | Default text shown when you create a new topic. |
</blockquote>
All template topics are located in the %TWIKIWEB% web. The WebTopicEditTemplate can be overloaded. When you create a new topic, TWiki locates a topic to use as a content template according to the following search order:

	1. A topic name specified by the =templatetopic= CGI parameter.
	1. <nop>WebTopicEditTemplate in the current web
	1. <nop>WebTopicEditTemplate in the %TWIKIWEB% web

---++++ Edit Template Topics and Variable Expansion

The following variables get expanded when a user creates a new topic based on a template topic:

<blockquote>
| *Variable:* | *Description:* |
| =%<nop>DATE%= | Current date, e.g. =%DATE%= |
| =%<nop>WIKIUSERNAME%= | User name, e.g. =%WIKIUSERNAME%= |
| =%<nop>URLPARAM{"name"}%= | Value of a named URL parameter |
| =%<nop>NOP%= | A no-operation variable that gets removed. Useful to prevent a SEARCH from hitting an edit template topic; also useful to escape a variable like =%<nop>URLPARAM%<nop>NOP%{...}%= |
| =%<nop>NOP{ ... }%= | A no-operation text that gets removed. Useful to write-protect an edit template topic, but not the topics based this template topic. See notes below. Example:%BR% =%<nop>NOP{%BR%&nbsp; &nbsp;* Set&nbsp;ALLOWTOPICCHANGE = <nop>Main.TWikiAdminGroup%BR% }%= |
</blockquote>

__Notes:__
	* Unlike other variables, =%<nop>NOP{ ... }%= can span multiple lines. 
	* The scan for the closing =}%= pattern is "non-greedy", that is, it stops at the first occurance. That means, you need to escape variables with parameters located inside =%<nop>NOP{ ... }%=: Insert a =%<nop>NOP%= between =}= and =%=. Silly example: =%<nop>NOP{ %<nop>GMTIME{"$year"}%<nop>NOP%% }%=.

All other variables are unchanged, e.g. are carried over "as is" into the new topic.

---++++ Template Topics in Action

Here is an example for creating new topics based on a specific template topic:

<form name="new" action="%SCRIPTURLPATH%/edit%SCRIPTSUFFIX%/%INTURLENCODE{"%WEB%"}%/">
	* New example topic: 
	  <input type="text" name="topic" value="ExampleTopic%SERVERTIME{$yearx$mox$day}%" size="23" />
	  <input type="hidden" name="templatetopic" value="ExampleTopicTemplate" />
	  <input type="hidden" name="topicparent" value="%TOPIC%" />
	  <input type="hidden" name="onlywikiname" value="on" />
	  <input type="hidden" name="onlynewtopic" value="on" />
	  <input type="submit" value="Create" />
	  (date format is <nop>YYYYxMMxDD)
</form>

The above form asks for a topic name. A hidden input tag named ==templatetopic== specifies ExampleTopicTemplate as the template topic to use. Here is the HTML source of the form:

<pre>
&lt;form name="new" action="%<nop>SCRIPTURLPATH%/edit%<nop>SCRIPTSUFFIX%/%<nop>INTURLENCODE{"%<nop>WEB%"}%/"&gt;
	* New example topic: 
	  &lt;input type="text" name="topic" value="ExampleTopic%<nop>SERVERTIME{$yearx$mox$day}%" size="23" /&gt;
	  &lt;input type="hidden" name="templatetopic" value="ExampleTopicTemplate" /&gt;
	  &lt;input type="hidden" name="topicparent" value="%<nop>TOPIC%" /&gt;
	  &lt;input type="hidden" name="onlywikiname" value="on" /&gt;
	  &lt;input type="hidden" name="onlynewtopic" value="on" /&gt;
	  &lt;input type="submit" value="Create" /&gt;
	  (date format is &lt;nop&gt;YYYYxMMxDD)
&lt;/form&gt;
</pre>

The =edit= scipt understands the following parameters, typically supplied by HTML input fields:

<blockquote>
| *Parameter:* | *Description:* |
| =topic= | Name of topic to create. Can be set in a text field, or is set programmatically (e.g. with a sequential number) |
| =onlywikiname= | If set, TWiki will complain if the topic name is not a WikiWord |
| =onlynewtopic= | If set, TWiki will complain if a topic of the same name already exists |
| =templatetopic= | The name of the template topic, e.g. topic used to copy the initial content |
| =topicparent= | Sets the parent topic |
| =TopicClassification= | Assuming the template topic has a form with a field called "TopicClassification", it will set the value of the field |
| =anyname= | Any parameter can passed to the new topic; if the template topic contains =%<nop>URLPARAM{"anyname"}%=, it will be replaced by its value |
</blockquote>

%T% *TIP:* You can use the =%<nop>WIKIUSERNAME%= and =%<nop>DATE%= variables in your topic templates to include the signature of the person creating a new topic. The variables are expanded into fixed text when a new topic is created. The standard signature is: <br />
==-- %<nop>WIKIUSERNAME% - %<nop>DATE%==

---++ Templates by Example

Attached is an example of an oops based template =oopsbase.tmpl= and an example oops dialog =oopstest.tmpl= based on the base template. %A% *NOTE:* This isn't the release version, just a quick, simple demo.

---+++ Base template oopsbase.tmpl

The first line declares a delimiter variable called "sep", used to separate multiple link items. The variable can be called anywhere by writing =%<nop>TMPL:P{"sep"}%=

<blockquote>
<table border="1" cellspacing="0" cellpadding="1" bgcolor="#f5f5f5">
<tr><td>
<pre>
%<nop>TMPL:DEF{"sep"}% | %<nop>TMPL:END%
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt; %<nop>WIKITOOLNAME% . %<nop>WEB% . %<nop>TOPIC% %.TMPL:P{"titleaction"}%&lt;/title&gt;
  &lt;base href<nop>="%<nop>SCRIPTURL%/view%<nop>SCRIPTSUFFIX%/%<nop>WEB%/%<nop>TOPIC%"&gt;
  &lt;meta name="robots" content="noindex"&gt;
&lt;/head&gt;
&lt;body bgcolor="#FFFFFF"&gt;
&lt;table width="100%" border="0" cellpadding="3" cellspacing="0"&gt;
  &lt;tr&gt;
	 &lt;td bgcolor="%<nop>WEBBGCOLOR%" rowspan="2" valign="top" width="1%"&gt;
		&lt;a href<nop>="%<nop>WIKIHOMEURL%"&gt;
		&lt;img src="%<nop>PUBURLPATH%/wikiHome.gif" border="0"&gt;&lt;/a&gt;
	 &lt;/td&gt;
	 &lt;td&gt;
		&lt;b&gt;%<nop>WIKITOOLNAME% . %<nop>WEB% . &lt;/b&gt;&lt;font size="+2"&gt;
		&lt;B&gt;%<nop>TOPIC%&lt;/b&gt; %<nop>TMPL:P{"titleaction"}%&lt;/font&gt;
	 &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr bgcolor="%<nop>WEBBGCOLOR%"&gt;
	 &lt;td colspan="2"&gt;
		%<nop>TMPL:P{"webaction"}%
	 &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
--- ++ %<nop>TMPL:P{"heading"}%
%<nop>TMPL:P{"message"}%
&lt;table width="100%" border="0" cellpadding="3" cellspacing="0"&gt;
  &lt;tr bgcolor="%<nop>WEBBGCOLOR%"&gt;
	 &lt;td valign="top"&gt;
		Topic &lt;b&gt;%<nop>TOPIC%&lt;/b&gt; . {
		  %<nop>TMPL:P{"topicaction"}%
		}
	 &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
</pre>
</td></tr>
</table>
</blockquote>

---+++ Test template oopstest.tmpl

Each oops template basically just defines some variables and includes the base template that does the layout work.

<blockquote>
<table border="1" cellspacing="0" cellpadding="1" bgcolor="#f5f5f5">
<tr><td>
<pre>
%<nop>TMPL:DEF{"titleaction"}% (test =titleaction=) %<nop>TMPL:END%
%<nop>TMPL:DEF{"webaction"}% test =webaction= %<nop>TMPL:END%
%<nop>TMPL:DEF{"heading"}%
Test heading %<nop>TMPL:END%
%<nop>TMPL:DEF{"message"}%
Test =message=. Blah blah blah blah blah blah blah blah blah blah blah...

	* Some more blah blah blah blah blah blah blah blah blah blah...
	* Param1: %<nop>PARAM1%
	* Param2: %<nop>PARAM2%
	* Param3: %<nop>PARAM3%
	* Param4: %<nop>PARAM4%
%<nop>TMPL:END%
%<nop>TMPL:DEF{"topicaction"}%
Test =topicaction=:
[<nop>[%<nop>WEB%.%<nop>TOPIC%][OK]] %<nop>TMPL:P{"sep"}%
[<nop>[%<nop>TWIKIWEB%.TWikiRegistration][Register]] %<nop>TMPL:END%
%<nop>TMPL:INCLUDE{"oopsbase"}%
</pre>
</td></tr>
</table >
</blockquote>

---+++ Sample screen shot of oopstest.tmpl

With URL: ==.../bin/oops/Sandbox/TestTopic2?template=oopstest&param1=WebHome&param2=WebNotify==

<blockquote>
| <img src="%ATTACHURLPATH%/testscreen.gif" width="589" height="304" alt="testscreen.gif"> |
</blockquote>

---++ Known Issues

	* A drawback of referring to a master template is that you can only test a template from within TWiki, where the include variables are resolved. In the previous system, each template was a structurally complete HTML document with a =.tmpl= filename extension - it contained unresolved =%VARIABLES%=, but could still be previewed directly in a browser.

-- TWiki:Main.PeterThoeny - 30 Dec 2004 %BR%
-- TWiki:Main.MikeMannix - 14 Sep 2001 %BR%
-- TWiki:Main.DavidLeBlanc - 11 Mar 2002
%META:FILEATTACHMENT{name="testscreen.gif" attr="h" comment="Example of oopstest.tmpl rendered" date="1026977240" path="C:\Data\Temp\testscreen.gif" size="9566" user="PeterThoeny" version="1.2"}%
%META:TOPICMOVED{by="MikeMannix" date="1000277381" from="TWiki.TWikiTemplateSystem" to="TWiki.TWikiTemplates"}%
