Quick links: Content - sections - sub sections
EN FR

Jelix includes its own template engine, jTpl, bases on the template engine Castor. 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 instantiate 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 output it directly.

Template files

A template file is made of HTML, XML 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, etc.

The syntax used in jTpl is a mix of the one used in smarty and the PHP syntax. 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; ?>

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)
  • $j_lang: current lang code
  • $j_country: current country code
  • j_assetsRevision: the value of the configuration parameter assetsRevision
  • j_assetsRevisionParameter: the value of the configuration parameter assetsRevisionParameter
  • j_assetsRevQueryUrl: the part to add to an url for assets revision (concatenation of assetsRevisionParameter, = and assetsRevision)

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>

Escaping content

By default content variables are inserted as is into the generated content. This may be not what you want. You would escape some characters, like < and > in HTML, so the browser will not perform these characters as tags.

So you should escape content variable:

  • by using the eschtml or escxml modifier: {$myvar|eschtml}
  • or by activating the auto-escaping: add a {! autoescape !} tag at the beginning of your template. All output of variables (with a tag {$..}) will be escaped.
    • If there is already an eschtml modifier, it will not add an additionnal escape process.
    • If you don't want to escape a variable, use the raw modifier: {$myHTMLcontent|raw}

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.

Personalized 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")')}

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 accessible into the included template.

If you don't want to share variables into the included template, you should use the {fetchtpl} tag. It is useful to include a template recursively.


 <div>
   ...
   {fetchtpl 'mymodule~sharedcontent'}
 </div>

Before using the {include} or {fetchtpl} tag, first consider using zones. In many case, it is better, because its generated content may be stored in a cache.

Macros

In a template, you may want to repeat a piece of template without using a loop. You could include several time an other template, but for little piece of template, this slower than the use of a macro.

A macro is a part of a template declared with the {macro} tag. A macro have a name and it is like a function in PHP.

Example of the declaration:


{macro 'myblock'}
<p>This is a block, displaying the value of $val: {$val}</p>
{/macro}

The name is set using the syntax of a PHP string. Variables or any other language syntax are not allowed.

Variables used inside the block can be variables declared into the template. The scope is global. You can use any template plugin, statements etc.

To call a macro, use {usemacro}:


This is my piece of html:
{usemacro 'myblock'}

...
I can display my piece of html again:
{usemacro 'myblock'}

If $val equals 'hello', the results will be :


This is my piece of html:
<p>This is a macro, displaying the value of $val: hello</p>

...
I can display my piece of html again:
<p>This is a macro, displaying the value of $val: hello</p>

You can declare parameters to a macro. Indicate parameters like for a PHP function (i.e. $foo), and use parameters inside the macro like any other variables.


{* declaration of the macro *}
{macro 'myblock', $name, $result}
<p>This is a macro with parameters.<p>
<ul>
    <li>name= {$name}</li>
    <li>{if $result == true}this is green{else}this is red{/if}</li>
</ul>
<p>You can still see the value of $val: {$val}</p>
{/macro}

{* usage of the macro *}

{usemacro 'myblock', 'SuperGuppy', true}

Declared parameters are not usable outside the macro. If there is a template variable with the same name, the value of the template variable is replaced by the value of the parameter inside the macro, but is restored after the call of the macro.

Macro declared into an included template can be used in the template caller.

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.

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 app/themes/default/. So the app/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