If you've been in web-frontend programming business for a while you will undoubtly notice that a good look of your software is sometimes as important as it's functionality: it should be a pleasure to the eyes when one has to work with the software a few hours a day. The standard widget set's layout is designed to be fast over very slow connections but it doesn't look very nice *sigh*.
One solution to this problem is to write an own widget set but often you don't want to create HTML templates yourself. Especially if you're a programmer you're happy if you can get HTML code done by an artist which is ready to get plugged in to your program. The artist should only have to know some extra tags he can place in his HTML code to fill in dynamic content. And since you can focus just on the data, your code will be more clean.
Let's take a look at a view function that displays a tables contents the traditional way:
function show_table ($this) { $p =& $this->ui; $p->headline ('Table listing'); $p->open_source ('table'); if ($p->query ()) { while ($p->get ()) { $p->inputline ('surname'); $p->inputline ('name'); } } else $p->msgbox ('No entries found.'); $p->close_source (); }
The code is quite straightforward. After printing the title we open a source, select a result and print widgets for each field. Surely an artist is not interested about how to fetch a result set. He wants the result set to be already there and to repeat a part of the template for each result. Some parts of the template should be used conditionally (e.g. status messages).
xml_template class method exec() takes the name of a template and an array of data keyed by names that can be matched within the template. After the tags were replaced, the template is echoed. Before using exec(), the tk_template module must be initialised so you can get form names und useful urls normally used in wiget sets. In the following example we use the chached version of xml_template:
<? include 'admin_panel/tk/template.php'; include 'text/xml/template__cached.class'; finction init (&$this) { # ... other initialisations... tk_template_init ($this, new xml_template_cached ($this->db)); } function show_table ($this) { $p =& $this->ui; $res = array (); $p->no_update; # Avoid form generation in open_source(). $p->open_source ('table'); if ($p->query ()) { while ($p->get ()) { tk_template_get_field ($this, $r, 'surname'); tk_template_get_field ($this, $r, 'name'); $res['table'][] = $r; } } else $res['error'] = 'No entry found.'; $p->close_source (); $this->tk_template->exec ('show_table.html', $res); } ?>
This is show_table.html (virtually done by an artist):
<html> <head><title>Show table</title></head> <body> <h3>Contents of table</h3> <!-- Show error message if exists. --> <cms:if match="error"> <font color="red"><h3><cms:value match="error"/></font> </cms:if> <cms:if-not match="status"> <form action="<cms:form-action/>" method="post"> <table> <cms:list match="table"> <tr> <td><input type="text" value="<cms:value field="name"/>" name="<cms:name field="name"/></td> <td><input type="text" value="<cms:value field="surname"/>" name="<cms:name field="surname"/></td> </tr> </cms:list> </table> <input type="submit" value="Ok" name="<cms:value match="submit"/>"> </form> </cms:if> </body> </html>
Since the template contains a form for field of the result set so the user can edit and post them, we fetch a form field description using tk_template_field() which also stores the current value. tk_template() recognizes field descriptions automatically so you can store them like scalars.
tk_template() uses the XML scanner class shipped with the dev/con php base. To speed up the whole process of generating HTML output each template is read from the file once, scanned and stored to the database as a document tree which can be processed quite fast. To update a template, its entry in the database must be deleted. Alternatively the whole template table can be deleted since they'll be restored on demand.
In the following sections we'll explain the tk_template() functions in detail, followed by the tags available.
tk_template() uses a fixed set of tags that allow fetching scalar values and iterate over lists using the same block repeatedly as well as simple conditionally executed blocks that test if particular results were defined or not.
The template toolkit provides a very simple interface to the XML scanner. Widget and helper functions for it are also available but change a lot. If you can't afford to be interrupted by API changes, use an own copy of the files. You can find all (yet undocumented) extensions in directory admin_panel/tk/template/ext.