-
Notifications
You must be signed in to change notification settings - Fork 0
dev template syntax
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>
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'
?>
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.
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>
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>
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.
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 < world ></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.
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>
Variable name like true
, false
, null
and array
are not interpreted.
You can add anywhere in your html code a comment (mono or multiline)
{# this is a comment #}
<p>
Lorem ipsum...
</p>
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 %}
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.
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.
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>
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.
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>
- 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'.
-
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.
- len: Return the len of the string.
-
br: Transform newline character
\n
into<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.
- 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.
- 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'.
-
config(): Return the
Config
object. see: pixelpost\Config::create().