|
Template Basics The HTML package implements a templating engine. It means that it processes a template file to build the resulting responce document. The template file contains references to template variables as well as regular and special tags. The template parser processes the templates, replaces variable references with their values and executes special tags. Every template must be a well-formed XML file. The HTML package is UTF-8 based only, so you may include non-English letters in the template files, but they must be saved in the UTF-8 encoding. Note that since the HTML package uses XML parsers to process the templates, all tags' case must be preserved! Below is an example of a template:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>Hello, World!</title>
</head>
<body>
<h2>Hello, World!</h2>
</body>
</html>
As you can see, it's an ordinary XML file with the html root element. The body is a simple HTML file that would display the string "Hello, World!" in big bold letters. As this may seem simple, the templating in HTML help you develop very complex documents that are separated from the application code. The first step to this is the concept of template variables. A template variable is a key-value pair that gets preset by the application by calling the HTMLDocument::setVariable method. It takes two parameters: first is the name of the template variable (the key) and the second is the actual value of the variable. Let's consider the following example:
and the following template:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>Hello, World!</title>
</head>
<body>
<h2>Hello, {%name}</h2>
</body>
</html>
This will produce a document where the word "World" would be substituted with the request parameter name. The HTML package allows scope nesting. It means that each opening tag advances the template variable stack pointer, while each closing tag pushes it back. If the opening tag itself adds template variables, they will not overwrite the existing variables with the same names. Such tags are, for example, the HTMLShowObject or HTMLShowIterable. The former simply extracts all key-value pairs or properties of an array or object into the current variable stack:
and the template
will show the names of the three. The key attribute of the HTMLShowObject tag denotes the name of the template variable that holds an array or an object. The tag searches for the template variable folks which was set to contain a three-element array, applies the foreach loop to its keys and values and sets the three template variables. Inside the HTMLShowObject tag you can reference the three by the names of the corresponding keys in the array. However, after the tag is closed, the three variables will be destroyed, and accessing them will not show their values. To demonstrate how variable scope nesting works, let's modify the above code and template:
The resulting document will have the line "Kid: John Doe" dipslayed, followed by the Blacks family, and followed by "Kid: John Doe" again. This is how it happens: we set two template variables, one is a string named kid, and the second is an array with three elements, one of which is kid also. Before the HTMLShowObject tag, we have the original value of the kid variable. When the tag opens, it extracts the key-value pairs into the variable stack so that when the template processor encounters the {%kid} construct, it will find the 'Joe Black' value and output it. When the tag closes, the three variables will be lost, restoring the original value of the kid variable to the 'John Doe' value. If, however, we didn't include the 'kid'=>'Joe Black' element into the array, the output would contain the 'John Doe' as the kid of Blacks family, since then the template processor would look for the variable in the previous stacks. The HTML package also supports custom tags that may repeat content. For example, the HTMLShowIterable iterates over instances of the Iterable interface. These may include SQL query result sets, iterable arrays etc. In the case of database query result sets this tag will extract columns of the next record as the template variables on each iteration so you can access their values like in the previous examples:
The above would produce a list of two products and their prices. You can also use special tags and template variables to hide/display certain parts of the template. You achieve this by using the HTMLIfSet and HTMLIfNotSet tags. Their single attribute, key, should contain a name of the template variable that evaluates to boolean. These tags will test the value of the variable, and, based on that, will enable or disable the display of their content:
The example will display both paragraphs as there is the success variable present and the variable failure was not defined. Another important concept of the tempating system is the support for regions. A region basicly is a piece of template that can be repeated elsewhere in the template. You define a region once while you can reuse it multiple times. This allows both to speed up parsing of complex templates and also to ease the possible changes in the appearance of the region - instead of changing similar markup in many places, it will be possible to update markup in the region, and the changes will appear everywhere that region is displayed. You create regions with the HTMLRegion tag and display that with the HTMLShowRegion tag:
As you can see, each region is referred by name so that you can distinguish multiple regions. If you use template variables in the definition of the region, the actual values displayed will depend on the current variable scope, for example:
and the template:
will display the names of the two artists, regardless of the fact that the region was defined in the scope where the first singer's name was available. Starting from version 1.1.0.Stable the Freeform Framework supports inclusion of PHP processing instructions into the templates. They should contain valid PHP source code; in each PHP block it has read access to the currently available template variables as local variables. The block can echo or print strings that will be included into the resulting document with no further transformations, so you can create HTML markup in these blocks:
and the template:
will display bold capitalized name of the singer. You can eclose such blocks of PHP code into the tags that iterate content; on each iteration the values of the variables will change (consider the example code with two products above):
will automagically markup every price by 20%. Unlike reading the template variables, the code in these blocks cannot change the values of the template variables; doing so will not yield any result. Also note that this approach is against the MVC idea and should be only used if there is no possibility to create custom tags to do the actual work of producing formatted or complicated content. Starting with version 1.1.0.Stable the tags can access their attribute values as references to other template variables:
will produce this: Starting with 1.2.0.Alpha the html package supports the i18n API. It allows you to embed translateable message into the text nodes of template, as well as into the attribute values. Suppose you have a message file: [en_Official] hello="Hello!" send="Submit" and somewhere in your action:
then a template:
will produce: Hallo! |
|