Skip to content

dev template syntax

Seza edited this page Jun 24, 2012 · 15 revisions

Template engine

Pixelpost template engine is a powerful and fast engine. Less than 800 LOC and simple cache feature, it mostly follow the Django template syntax, have lot of features.

How look like your php file ?

4 methods to know : create(), assign() , render() , publish().

	<?php

	Template::create()
		->assign('foo', $foo)
		->publish('my_template.tpl');

	?>

How look like your template file ?

	<p>
		Hello {{ foo }} !
	</p>

For the developer

Assign data to a template

You can use the assign() method or simply set a property to the template object.

	<?php

	// new Template
	$tpl = pixelpost\core\Template::create();

	// set foo to $value
	$tpl->assign('foo', $value);

	// set foo to $value by other way
	$tpl->foo = $value;

	?>

So why use the assign() method ?
Template class is designed to follow a fluent interface. With assign() method you can chain your call to the methods's Template.
There is also a little difference by using assign() method. When you set a property, his value is not checked, or changed. The assign method provide a little of magic when you pass an array to it.

	<?php

	// some data
	$data = array('foo' => 'bar', 'bar' => 'baz');

	// new Template and add data to it
	$tpl = pixelpost\core\Template::create()->assign($data);

	echo $tpl->foo; // return 'bar'
	echo $tpl->bar; // return 'baz'

	?>

Render data in a template file

You have two methods, render() and publish(), for rendering a template file.
They work as the same way at the difference that the first one return a string and the second one print him to the stdout.

	<?php

	// print the rendered template file
	$tpl->publish('file.tpl');

	// print the rendered template file
	echo $tpl->render('file.tpl');
	?>

NOTE: The path is always relative to the plugins file path of the app.

For the designer

Inline level

Usage of {{ }}

You can use the {{ and }}tags to print value in your template.

	<title>{{ title }}</title>

You can use some basic php operation in your template:

	<p>
		Addition is a math operation like: 2 + 3 = {{ 2 + 3 }}
	</p>

You can use parenthesis to group your operation, the .permit to access to an object property. Using the brackets [] to array access or parenthesis () to call a method is possible too.

	<p>
		The amount of your order is: {{ order.total['vat'] }}
	</p>

Local variable and constant

You can use the @ tag to refer a constant or # to refer a local variable.

	<p>
		This is the php version {{ @PHP_VERSION }}
	</p>

	{: #number = 3 :}

	<p>
		There is {{ #number }} apples on the table.
	</p>

Usage of {: :}

As you can see in the above example, there is another one inline tag: {: and :}. It works exactly as the same manner as {{ and }} but don't print anything. This is very useful to set some local variable and make some operation.

Filters

The most important and powerful feature with inline tag is the filtering possibility. You can add a filter to any value (variable, string, parenthesis). An example is always more explicit.

	<!-- assume: $tpl->title = "hello < world >"; -->

	<title>{{ title|capital|escape }}</title>

	<!--
	- filter capital upcase the first letter of the first word
	- filter escape remove unauthoriszed char in html content
	- result is:

	<title>Hello &lt; world &gt;</title>
	-->

You can also use filter with arguments

	{: #fruits = array('apple', 'banana', 'orange') :}

	<p>
		Choose a fruit between: {{ #fruits|join(' or ') }}
	</p>

	<!-- Choose a fruit between: apple or banana or orange -->

There is lot of filters built in the template engine, an explicit list is provided later.

Escaping character

You want to use {{, }}, {:, :}, {#, #}, {% and %} in you html code without this is interpreted by the template engine. You have to escape it like

	<p>
		You can print a value in your template with {{ '{{' }} and {{ '}}' }} tag.
	</p>

Uninterpreted variable name

Variable name like true, false, null and array are not interpreted.

Block level

Comments

You can add anywhere in your html code a comment (mono or multiline)

{# this is a comment #}
	<p>
		Lorem ipsum...
	</p>

Raw Blocks

A raw blocks is a block which is not interpreted by the template engine. Very useful to print template code or more other stuff...

	{% raw %}
	<p>
		All code like this: {{ title }} is not interpreted. This work like <pre> in html.
	</p>
	{% endraw %}

Blocks

One of the most complex but powerful feature in a template engine is the block feature.

You can create blocks like:

	{% block Title %}This is my page title{% endblock Title %}

	{% block Content %}This is my page content{% endblock %}

Here we have created two blocks: Title and Content. As you can see a block have a name, this is mandatory but it is not mandatory to repeat that name is the closing tag.

You can use the content of a block with the {% display %} tag. See it in action in the next example.

NOTE:
If a block is not defined when you use {% display %}, the block is automatically created and set empty.

Extends

Blocks are not very useful without the possibly of extending them within a template file.

Keep in mind the previous example, let just tweak it a little:

	{% extends my_plugin/tpl/main.tpl %}

	{% block Title %}My Page Title{% endblock Title %}

	{% block Content %}This is my page content.{% endblock %}

An now the content of my_plugin/tpl/main.tpl:

	<!DOCTYPE html>
	<html>
		<head>
			<title>{% block Title %}My Site: {% child %}{% endblock %}</title>
		</head>
		<body>
			<h1>{% display Title %}</h1>
			<p>
				{% block Content %}{% endblock %}
			</p>
		</body>
	</html>

And the result is:

	<!DOCTYPE html>
	<html>
		<head>
			<title>My Site: My Page Title</title>
		</head>
		<body>
			<h1>My Site: My Page Title</h1>
			<p>
				This is my page content.
			</p>
		</body>
	</html>

As you can see the {% child %} tag permit to include the child content in a parent block. If it is not used the parent block content is erased by the child block content. As opposite the {% parent %} tag can be use in a child to include the parent content.

We can use {% display Content %} instead of {% block Content %}{% endblock %}. In this example this will work fine.

NOTE: The extends file is always relative to the plugins folder in the application.

include

In the same way you extends a template file, you can include one in another one. There is difference between extends and include:

  • When you extends a file: Blocks are interpreted and extended block's are replaced by their new content.
  • When you include a file: Blocks are not interpreted. The included content is just pushed into the template which make the include call.
	<!DOCTYPE html>
	<html>
		<head>
			<title>My Page Title</title>
		</head>
		<body>
			{% include my_plugin/tpl/header.php %}
			{% include my_plugin/tpl/content.php %}
			{% include my_plugin/tpl/footer.php %}
		</body>
	</html>

If, elseif, else

You can simply add conditional block with {% if %}, {% elseif %}, {% else %} and {% endif %} tags.

	<p>
		{% if my_var|exists %}
			This is my var value: {{ my_var }}
		{% else %}
			my_var is not set.
		{% endif %}
	</p>

The condition in {% if %} and {% elseif %} tag is interpreted as the same way as inline content.

For loop

There is one method for looping in the template engine: the {% for %} tag.

	<ul>
		{% for item in listItems %}
			<li>this is item: {{ item }}</li>
		{% endfor %}
	</ul>

You can add an optional tag {% elsefor %} is the array (or object) is empty.

	<ul>
		{% for item in listItems %}
			<li>this is item: {{ item }}</li>
		{% elsefor %}
			<li>There is no item in the list</li>
		{% endfor %}
	</ul>

You can also retreive the keys of a list:

	<ul>
		{% for key, item in listItems %}
			<li>this is item: {{ key . ':' . item }}</li>
		{% elsefor %}
			<li>There is no item in the list</li>
		{% endfor %}
	</ul>

If you need to count each item, know if it is the first item of the list etc... There is a simple solution: the loop object.

In each for loop, there is a loop object you can call to retrieve this value:

  • index: The item's number count (start to 1).
  • index0: The item's number count (start to 0).
  • length: The numbers of items in the list.
  • revindex: The item's number count to the end (start to length).
  • revindex0: The item's number count to the end (start to length - 1).
  • first: Boolean set to true if it's the first item.
  • last: Boolean set to true if it's the last item.
	{#
		- filter even return true if the number is 0,2,4,6...
		- filter if return the first param if value is true, else return the second one.
	#}
	<table>
		{% for product in cart %}
		<tr style="background-color:{{ loop.index|even|if('blue', 'white') }}">
			<td>{{ product.name }}</td>
			<td>{{ product.quantity }}</td>
			<td>{{ product.price }}</td>
		</tr>
		{% endfor %}
	<table>

List of built-in filters

Apply on mixed elements

  • exists: Return true if variable is set.
  • empty: Return true if variable is empty.
  • default(value): Return a value 'value' if a variable is not set.
  • if(yes, no): Return 'yes' if variable is true else return 'no'.

Apply on DateTime object

  • date('longer'): Return the date like: 'l jS \of F Y'

  • date('long'): Return the date like: 'D jS \of M Y'

  • date('small'): Return the date like: 'jS F Y'

  • date('smaller'): Return the date like: 'd-m-Y'

  • date('iso'): Return the date like: 'Y-m-d'

  • datetime('longer'): Return the datetime like: 'l jS \of F Y, h:i A'

  • datetime('long'): Return the datetime like: 'D jS \of M Y, h:i A'

  • datetime('small'): Return the datetime like: 'jS F Y h:i A'

  • datetime('smaller'): Return the datetime like: 'd-m-Y h:i A'

  • datetime('iso'): Return the datetime like: 'Y-m-d H:i:s'

  • time('longer'): Return the datetime like: 'h:i A'

  • time('long'): Return the datetime like: 'h:i A'

  • time('small'): Return the datetime like: 'h:i A'

  • time('smaller'): Return the datetime like: 'h:i A'

  • time('iso'): Return the datetime like: 'H:i:s'

NOTE:

  • Each methods accept a second boolean parameter that's append the timezone to the date (format: T).
  • With no parameter, the filter fall back to the small format.

The generic:

  • date(format): Return the date formatted to 'format'

NOTE: The timezone is set to the configured user timezone.

Apply on strings

  • len: Return the len of the string.
  • br: Transform newline character \ninto <br /> html tag.
  • url: url encode the string.
  • asset: transform a formatted string like plugin_name::asset_file in a url pointing to the asset.
  • base64: base 64 encode the string.
  • strip: Remove all html tag in the string.
  • upper: Up case the string.
  • lower: Down case the string.
  • reverse: Reverse the string.
  • capital: Up case the first letter of the string.
  • title: Up case the first letter of each word in the string.
  • escape: Escape all html char in the string.
  • sub(start): return the substring by starting at 'start' character.
  • sub(start, end): Same as before but finish at 'end' character.
  • replace(old, new): Replace 'old' by 'new'.
  • split(sep): Return an array by splitting the string at 'sep'.
  • event: Take the string as an event name, throw this event and return the response parameter as array.

Apply on numbers

  • number: Format a number with 2 decimals.
  • even: Return true is number is even.
  • odd: Return true is number is odd.
  • abs: Return the absolute value.
  • neg: Return the negative value.
  • between(min, max): Check if a number if between 'min' and 'max' both included.

Apply on array

  • first: Return the first item of the array.
  • last: Return the last item of the array.
  • sort: Sort the array (preserve key).
  • rsort: Sort the array in reverse order (preserve key).
  • nsort: Sort the array in natural order (preserve key).
  • length: Return the number of item in the array.
  • keys: Return a new array contains all the keys.
  • values: Return a new array contains all the values.
  • join: Return a string by joining all values with a space.
  • join(sep): Return a string by joining all values with 'sep'.

dedicated template method

  • config(): Return the Config object. see: pixelpost\Config::create().
Clone this wiki locally