- ^ Jelix components
- jTpl, template engine
- Zones
- jDao: relational object mapping
- Classic forms
- jForms: automatic forms
- jDb: accessing to SQL database
- jKVDb: accessing to key/value databases
- jUrl: automatic urls
- jAuth : authentication system
- jAcl2 : rights management
- jLocale: localization
- jEvents: communication between modules
Chapter: jTpl, template engine
^ Jelix components | Zones » |
− Table of content
Jelix includes its own template engine: jTpl. Templates are files with the ".tpl" extension and located in the templates
directory of modules.
The jTpl object ¶
The jTpl
object is meant to generate the content specified in a template file, with data input by you, following the instructions in the template.
Some of jResponse*
objects or jZone
instanciate for you a jTpl object. For example the body
property of the jResponseHtml
object is a jTpl
object, as for the _tpl
property of jZone
.
In other case, you have to instanciate a jTpl
:
$tpl = new jTpl();
Here are the most important methods to know.
assign ¶
$tpl->assign($name, $value);
This method allows you to create a template variable. A template variable is only accessible in the template level. You will then use this method to pass data (static values, objects, iterators, etc) to the template to be able to use it for content generation.
You can also create or modify a variable directly in the template, using:
{assign $name = $value}
- *Important** : the name of a template variable should follow syntaxic rules for a name of a PHP variable. the name should contain only letters, numbers or "_".
assignByRef ¶
Same purpose of the assign
method, but the value is passed by reference, so you can assigne huge array without duplicating them in memory.
assignIfNone ¶
Same purpose of the assign
method, but the value is assigned only if the variable doesn't exist.
assignZone ¶
$tpl->assignZone($name, $zoneSelector, $params);
The $params parameters is optional. This method is a shortcut for:
$tpl->assign($name, jZone::get($zoneSelector, $params));
assignZoneIfNone ¶
Same as assignZone
, but the content of the zone is assigned only if the variable doesn't exist.
get ¶
If you want to get the value of a template variable that is already initialized, you can use this method :
$value = $tpl->get('foo');
Generating the content ¶
After variables are created and initialized, you can call the fetch
method to generate the content of the template, and to retrieve it. You give the selector of the file template as the first parameter.
$content = $tpl->fetch('mymodule~mytemplate');
You call this method only if you have instanciate the jTpl object. In other case, you needn't to call it.
There is an other method you won't never call, since jResponse objects use it : display
.
$tpl->display('mymodule~mytemplate');
It generates the content and ouput it directly.
Template files ¶
A template file is made of HTML, XUL or whatever you want if it corresponds to the type of the response. It contains also some instructions to incorporate values that you will define, instructions to repeat the generation of parts of HTML, XUL, etc.
The syntax used in jTpl is in the middle of the one used in smarty and the one of PHP. The goal is to have templates readable enough, easy to modify and not forcing a syntax that is too different from PHP. All this proposing features that PHP doesn't have and adapted to Jelix.
Do not forget that most of the templates that you will make shouldn't be entire files. Especially for the HTML responses, your templates must contain only what is between the <body>
and </body>
tags, the rest is automatically generated thanks to jResponseHtml
.
Instruction syntax ¶
Instructions in jTpl are specified between curly braces : {instruction ...}
If you want to include curly braces in your template, outside of a jTpl instruction, you can use {ldelim}
for "{", or {rdelim}
for "}".
If you have a block with several curly braces, like in a piece of code of javascript, you can use {literal}
instead of {ldelim}
or {rdelim}
.
<script type="text/javascript">
{literal}
for(i=0;i<max;i++) {
if(foo){ ...}
}
{/literal}
</script>
If you want to put comments which won't be include in the resulting content, use {*...*}
<p>bla bla</p>
{* this is a comment *}
You can write an instruction on several lines:
<div>
{zone
'foo~bar',
array(
'foo1'=>$foo1,
'foo2'=>$foo2)}
</div>
Expressions ¶
A jtpl expression is identical to a PHP expression, and return a value, like in PHP. You can use classical PHP operators, objects, array etc. You can use also template variables, like any PHP variables. You use jtpl expressions as arguments of jtpl instructions. Here is a simple expression:
$template_variable
An expression can also contain some selector of locales, by using a specific syntax. This selectors should be introduced between two "@".
@my_module~key.localized.string@."fooo bar"
It is equal to this PHP code :
jLocale("my_module~key.localized.string")."fooo bar"
Inside a locale key, you can use some template variables. It allows to construct dynamically a locale key:
@my_module~key.$variable.string@."fooo bar"
It is equal to this PHP code :
jLocale("my_module~key.".$variable.".string")."fooo bar"
Displaying an expression, a variable ¶
To display the result of an expression, you should put it between curly braces. The first element of the expression should be a variable or a locale selector.
{$myvariable}
{$myvariable * 3}
{$myvariable." - ".@mod~message.ok@}
{@modul~a.key.of.locale@."-".$anOtherVariable}
{@modul~a.key.$dynamique@."-".$anOtherVariable}
This is equal to
<?php echo $myvariable; ?>
<?php echo $myvariable * 3; ?>
<?php echo $myvariable." - ".jLocale::get("mod~message.ok"); ?>
<?php echo jLocale::get("modul~a.key.of.locale")."-".$anOtherVariable; ?>
<?php echo jLocale::get("modul~a.key.".$dynamique)."-".$anOtherVariable; ?>
Since Jelix 1.1, for more complex expressions , you can use the syntax with =
:
{=$myvariable}
{=intval($myvariable)*3}
Predefined constants ¶
Some variables are predefined so you have not to assign them:
- $j_basepath: it contains the url path of the directory of the application (this is the value of the parameter "basePath" in the configuration)
- $j_jelixwww: it contains the url path of the directory
jelix-www/
(this is the value of the parameter "jelixWWWPath" in the configuration) - $j_themepath: it contains the url path of the directory of the current theme in www
- $j_datenow: current date (aaaa-mm-jj)
- $j_timenow: current hour (hh:mm:ss)
- $j_locale: current locale code (the value of
jApp::config()->locale
)
Modifiers ¶
A modifier is a function which modify the output of an expression. You can use many modifiers at the same time. It works in fact like modifiers of Smarty:
{$avariable|upper}
{$avariable|upper|escxml}
{$aUrl|escurl}
It is equal to:
<?php echo strtoupper($avariable);?>
<?php echo htmlspecialchars(strtoupper($avariable));?>
<?php echo rawurlencode($aUrl);?>
Some modifiers, like those in the previous example, are simple aliases to some native PHP functions:
- upper (strtoupper)
- lower (strtolower)
- escxml and eschtml (htmlspecialchars)
- strip_tags (strip_tags)
- escurl (rawurlencode)
- capitalize (ucwords)
- stripslashes (stripslashes)
- upperfirst (ucfirst)
Many others are function defined in plugins for jTpl. See the list in the API reference
Modifiers with parameters ¶
Some modifiers need some parameters. You should put this parameters after a ":" after the modifier name, and you should separate parameters with ",". Parameters are expressions.
Example with the jdatetime modifier:
<p>The date is {$myDate|jdatetime:'db_date','timestamp'}.</p>
Control statements ¶
They are similar to statements of PHP, except that parenthesis are not required around conditions or expressions.
if, else, elseif ¶
{if condition_1} // code here {elseif condition_2} // code here {else} // code here {/if}
Note that some plugins are provided and are specific conditional statements, like ifacl2 'a.right'
. You can use the else
statement for all of them begining by "if".
while ¶
{while condition} // code here {/while}
foreach ¶
{foreach $iterator_or_array as $key=>$value} // code here {/foreach}
for ¶
{for expression} // code here {/for}
The expression should be identical as the expression of the for
in PHP.
break ¶
You can use {break}
to insert a break
instruction into a loop:
{while condition}
...
{if ...} {break} {/if}
....
{/while}
Functions ¶
Functions in a template are plugins you can use in a template. This plugins are simple PHP functions and you can create some kind of plugins.
The syntaxe of the call in a template is:
{function_name expression, expression,...}
You mustn't use parentheses around all parameters. Expressions are jtpl expressions, so similar to PHP expressions.
Note that some functions and other template plugins are callable in general only in a template used by a specific type of response. Some plugins are for HTML responses, some other plugins are for text responses.
Personnalized functions and modifiers ¶
If you want to have some new jtpl functions or modifiers, you can realized some plugins. See the documentation about it. This is simple.
An other solution is to declare the modifiers or the functions dynamically, by calling the jtpl methods registerModifier()
or registerFunction()
. To this methods, you should indicate a name which will used in the template, and a name of a php function which implements the modifier or the function. The arguments of the php function are the same of the php function of a jtpl plugin.
Meta informations ¶
There is a special tag: {meta}
. It doesn't change how the template is generated, it doesn't generate some content, and more important, it cannot be influenced by any other template instructions. Putting it inside an "if" statement for example, does nothing. The meta tag will be interpreted, even if the if statement is false. The meta tag exists only to provide informations for the code which uses the jtpl object.
The syntax is
{meta name expression}
Example: {meta author 'laurent'}
You can create all meta you want. Then this informations are available in the jTpl
object, by using the meta
method.
$tpl = new jTpl();
$metas = $tpl->meta('mymodule~thetemplate');
$metas['author']; // contains 'laurent'
Note: if you use a variable in the expression of a meta tag, this variable should be assigned from the jtpl object, not from other instruction in the template itself (like {assign ...}
).
Advanced meta informations ¶
Another type of meta tag allows you to automatically process meta data. Those are implemented through template plugins.
Their syntax is:
{meta_//plugin_name// name expression}
Example which uses the meta_html plugin. This plugin allows to modify the current html response: it can add a css stylesheet, a javascript link etc.
{meta_html css '/styles/my.css'}
{meta_html js 'fooscript.js'}
{meta_html bodyattr array('onload'=>'alert("charge")')}
Virtual Templates ¶
You can use templates that are not in files. These are called "virtual templates". Typically, you have a template in a string (retrieved from a database for example), and then you can generate the content into a string.
A simple example :
$template = ' hello
{$value}
world
{for $i=1;$i<=5;$i++}
{$i}
{/for}';
$tpl = new jTpl();
$tpl->assign('value', 'test');
$content = $tpl->fetchFromString($template, 'text');
As second argument, you can indicate the type of content (text
, html
...).
$content
will be:
hello
test
world
1
2
3
4
5
You can then inject this content into an other template for example.
Templates dedicated to a locale ¶
In a template, we saw that we can use {@foo.bar@} to include localized string. However, you can have many localized string, and so the template is less readable, and performance are lower.
There is a solution: create templates for each language. Of course, it means that you duplicate the code of the template, and so it is less easy to maintain them. So you should think if you prefer performance or easy modifications...
To create a template for each language, create sub-directories into the template directory. Their name should be a language code. Example: templates/fr_FR
, templates/en_US
etc. And save in each of this sub-directories a copy of your translated template.
Including a template into an other ¶
There is some case where you would like shared contents of a template with other templates. To do it, you will create a template file, and use the {include}
tag inside the template which will include the other template. You should give the selector name.
<div>
...
{include 'mymodule~sharedcontent'}
</div>
All template variables declared in the jtpl object will be accessibled into the included template.
Before using the include tag, first consider using zones, in many case, it is better.
Redefining a template ¶
Each module defines some template. If the module comes from an other project, or is shared by other application, you shouldn't modify the template, because each time you want to update this module, you should take car to not erase your modifications.
Fortunately, Jelix provide a system of theme, so you can redefine template without modify the original files.
The default theme is in the directory var/themes/default/
. So the var/themes/default/my_module/my_template.tpl
redefines the template my_module/templates/my_template.tpl
For more details, see the chapter on themes
Inside the template engine ¶
Jtpl templates are "compiled". Jtpl convert template to PHP files, and this php file are stored in the cache to increase performances. You can see them in temp/your_appname/compiled/templates/modules/your_module~your_template.php
, or for templates included in themes, look in temp/your_appname/compiled/templates/themes/theme_name/your_module~your_template.php
You can create your own plugin template, if you have particular needs or want to use your own tag(s) in a template. See plugins/tpl