Pluf : PHP 5 Framework   Download | Bug Tracking | Source | Documentation | Forum | Latest Changes | Home

The Pluf template language

You can use or not the templating system, but when you start to use it, you will have difficulties stopping as it is really easy to use and powerfull.

Why a Templating Engine?

This is the main question people have:

why do you need a templating engine when PHP is already built to provide this functionnality at its very core?

The main argument for the templating engine is that it saves time and reduces errors by doing the right stuff by default. Here are the two biggest points for me:

Escaping the Variables

When you want to display a variable let say $title in a page, with the variable coming user input, you need to do the following:

<?php echo(htmlspecialchars($title, 'UTF-8')); ?>

with the templating engine you write:

{$title}

The templating engine will automatically detect if the variable needs to be escaped or not and escape as needed. Your code is safe by default. Let say, you know the variable contains HTML and is safe to be displayed. You can write:

{$title|safe}

or in the code of the view you can mark the variable as safe:

$title = Pluf_Template::markSafe($title);

and then simply use {$title} in the code of the template. The templating engine will detect that the $title variable is safe and will not escape it. If you use wisely the markSafe method, you can have very clean templates where the designers do not have to think about all the gory details of security.

Internationalisation of the Templates

If you are writing an application that is then used by many people from different countries, you will translate the pages in different languages. This means that in the code you will do things like:

<?php echo _('Hello world'); ?>

With the templating engine you can do:

{trans 'Hello world'}

The power is coming when you need to translate and do substitution at the same time, for example, with the templating engine you can simply do:

{blocktrans}Hello {$user}, you are welcome!{/blocktrans}

You can learn more about internationalization.

Templates

Templates are simple text files. You can use them to generate any text-based format like XHTML, XML, CSV, etc.

Here is an example of a template:

 {extends 'base.html'}
 {block body}
 <h2>{$list.name|upper}</h2>
 {if $items}
 <ol>
 {foreach $items as $item}
 <li>
 <a href="{url 'Todo_Views::viewItem', array($item.id)}">{$item.item}</a>
 </li>
 {/foreach}
 </ol>
 {/if}
 <p><a href="{url 'Todo_Views::addItem', array($list.id)}">Create a new 
 item</a> | 
 <a href="{url 'Todo_Views::updateList', array($list.id)}">Update 
 the list</a></p>
 {/block}

What you can see is normal HTML tags together curly brackets {}. The curly brackets delimit tags and variables.

Template inheritance

The template inheritance is directly inspired by the Django template inheritance, because when you start to use it, you want all your templating systems to have this feature. Here is an example of a base template base.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Todo Test Application : {$page_title}</title>
</head>
<body>
<h1>{$page_title}</h1>
{block body}{/block}
<p><a href="{url 'Todo_Views::main'}">Home</a></p>
</body>
</html>

You can the definition {block body}{/block}, this means that here we have a block with the name body defined. Now, if you take the first template example, it was in the form:

 {extends 'base.html'}
 {block body}
 Some content here...
 {/block}

What it means is that when rendering this child template, it will first load the base.html template and detect that the body block is available and also overwritten in the child template. The result is that the final content of the body block will be the one of the child template.

If you define a block in the parent template and do not define it in the child, the content of the parent template is used. You can have multiple inheritance levels.

Variables

A variable is assigned to the template in your PHP code and is then available in the template in the form:

{$myvariable}

When the template engine find {$myvariable} it evaluates the content of the variable and replaces it with the result. For example, you put "Hello World!" in myvariable, the following template code:

<p>{$myvariable}</p>

will render as:

<p>Hello World!</p>

If you want to access the attributes of a variable representing an object, you can use a dot (.). For example:

{$user.last_name}

Filters

Variables can be modified, for example, in the template example you can find the fragment:

<h2>{$list.name|upper}</h2>

This means, take the name attribute of the list variable, convert it to uppercase and display it.

You can chain the filters to apply multiple filters on one variable. For example you could do:

<p>{$mytexte|upper|nl2br}</p>

to convert your text in uppercase and then convert the new line character to HTML line break.

Some filter take parameters, in that case you write the parameters after the name of the filter:

<p>{$modification_date|date:"%Y %m %d"}</p>

Tags

Tags do not start with the dollar ($) sign, but directly with the name of the tag. In the above example, you can find the following tags: extends, block, if, foreach, url. Some of the tags have a corresponding closing tag /if, /block, but some other don't.

Tags are more complex than variables as they can insert content in the template, change the rendering flow or loop on list of variables. See the reference below for more details.

if, else and elseif

These are simple control structure tags to display conditional information. For example you can have:

{if $title}
The title is: {$title}.
{else}
We do not have a title.
{/if}

or simply:

{if !empty($title)}The title is: {$title}.{/if}

if and elseif accept a condition which is evaluated as PHP code, you can use all the builtin PHP functions in the conditions.

foreach

Foreach is used to iterate through an array or a class implementing the [Iterator](http://www.php.net/spl) interface. You can use it the same way as the foreach PHP control block.

{foreach $array as $key => $value}
{$key}: {$value}<br />
{/foreach}

or:

{foreach $array as $value}
{$value}<br />
{/foreach}

Note: The foreach loops is often creating problems if you are using PHP 5.2.0 as the implementation of the Iterator class in this release of PHP has introduced some array handling issues.

while

The while loop is executed as long as the condition is true.

{while $skyisblue}The sky is blue.{/while}

You should structure your code not to create infinite loops!

assign

Assign a value to a variable. For example:

{assign $skyisblue = false}

You can then use the $skyisblue variable later in your template. Any kind of function call can be made in the assignement. For example:

{assign $title = mb_strtoupper($title)}

Now, $title is in upper case.

If you want to concatenate several strings into one big, you can use the ~ (tilde) character:

{assign $title = $title1~' and '~$title2}

This is the equivalent of the following PHP code:

 $title = $title1.' and '.$title2;

literal

The literal block is used to display verbatim content. That is, the code will be displayed without interpretation:

The assign tag is used that way:

{literal}
{assign $title = mb_strtoupper($title)}
{/literal}

This is useful when inserting JavaScript in your template.

block and superblock

See the template inheritance section later in this document.

trans, plural and blocktrans

See the internationalisation documentation to see how to use this tags to translate your application in multiple languages.

include

Include another template in the current template. If you are often using a piece of template and do not want to write it again and again and if you cannot use the template inheritance, you can include a template within another.

{include "path/to/your/template.html"}

The path is written the same way as what you would write to use a template from your PHP code. That is, you do not provide the full path to the file and the file will be searched through the folders defined in the 'template_folders' configuration variable.

Important Restrictions

The path is a fixed path. You cannot write:

{include $variable~"/path/to/template.html"}

The include template cannot contain inheritance block.

Comments

A comment is a piece of information that will not be displayed in the final rendering.

{* This is a comment,
   it can be over multiple lines and can contain
blocks {$variable} etc... *}

Basically, before rendering the template, the text between {* and *} is removed and then the rendering starts. This allows the template creators to write down some notes that will not be seen in the final result. This is great to comment your template.

Usage in the Views

Considering the minimalist template:

<html><body>
Hello {$name}!
</body></html>

You will use it the following way:

Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
return Pluf_Shortcuts_RenderToResponse('the-template.html',
                                       array(
                                             'name' => 'Foo Bar'
                                            ));

or with more details:

$tmpl = new Pluf_Template('the-template.html');
$context = new Pluf_Template_Context(array('name' => 'Foo Bar'));
$output = $tmpl->render($context);
return new Pluf_HTTP_Response($output);

Security Against XSS

All the variables are automatically escaped in the output. If you want to display the content of a variable without escaping, you need to mark it as safe from within the code (the best) or from within the template (not so good, you should not worry about those details in the templates).

Mark a string as safe in the code:

$safe_string = Pluf_Template::markSafe('<b>String with HTML</b>');

Mark a safe string in the template with the safe output filter:

{$my_string|safe}

Builtin Variable Filters

upper

Convert a string to uppercase using the PHP strtoupper function.

lower

Convert a string to lowercase using the PHP strtolower function.

count

Count the number of elements in an array using the PHP count function.

md5

Returns the md5 hash of a string using the PHP md5 function.

escape

strip_tags

escurl

capitalize

debug

dump

nl2br

trim

safe

Mark a string as safe.

date

Convert a date/time from GMT to local and format it using the strftime function.

For example:

{$article.creation_dtime|date}

or:

{$article.creation_dtime|date:"%b %e, %Y"}

time

Format a unix timestamp using the PHP date function.

{$timestamp|time:"Y-m-d H:i:s") 

dateago and timeago

Report issues in the documentation

If you find errors or issues in the documentation, report a bug. We will update the documentation accordingly.

Pluf © 2005-2008 Loïc d'Anterroches, supported by Céondo Ltd.