public $default_filter = 'Template::sanitize'
Override this to change the default filter for variables.
public $controller
The controller object used to run includes. The controller can be any object that satisfies the following interface:
interface AbstractController {
public function run ($uri, $data = array ());
}
public __construct ($charset = 'UTF-8', $controller = false)
Constructor method sets the charset and receives a controller object.
public render ($template, $data = array ())
Render a template with the given data. Generate the PHP template if necessary.
public render_string ($template, $data = array (), $file_prefix = '_string_')
Render a template from a string with the given data. Generates the PHP and caches it.
public render_preview ($template, $data = array ())
Render a template string for preview purposes. Generates a temporary cached version but unlinks it immediately after use.
public parse_template ($val)
Replace values from template as string into PHP code equivalents. Note that this method never receives the original data sent to the template, so it can't accidentally embed user data into the PHP code, eliminating the possibility of exposing a security hole.
public replace_vars ($regs)
Replace variables of the form:
{{ some_var }}
Also applies filters, which can take the following forms:
{{ some_var }} # defaults to Template::sanitize()
{{ some_var|none }} # no filter
{{ some_var|strtoupper }} # filters are php functions
{{ some_var|strrev|strtolower }} # filters can be chained
{{ some_var|my_function }} # calling a custom function
{{ some_var|date (%s, "F j, Y") }} # use %s for multiple-parameter functions
public replace_includes ($regs)
Replace {! app/handler?param=value !}
with calls to Controller::run()
.
You can also substitute sub-expressions for values using []
tags, like
this: {! app/handler?param=[varname] !}
public hard_codes ($regs)
Replace {# app/handler?param=value #}
with the hard-coded output from
a call to Controller::run()
. Note that you cannot use sub-expressions
here like you can with the dynamic {! app/handler !}
calls.
public run_includes ($val)
Run any includes and include their output in the return value. Primarily
for page body in the admin app. This only evaluates {! app/handler !}
style tags.
public replace_strings ($regs)
Replace strings with calls to __ ()
for multilingual sites.
Translatable strings take the following form using either double
or single quotes:
{" some text here "}
{' some text here '}
public static sanitize ($val, $charset = 'UTF-8', $label = '')
Sanitize a value for safe output, helping to prevent XSS attacks. Please note that this method can still be insecure if used in an unquoted portion of an HTML tag, for example:
Don't do this:
<a href="/example" {{ some_var }}>click me</a>
But this is okay:
<a href="/example" id="{{ some_var }}">click me</a>
And so is this:
<span id="some-var">{{ some_var }}</span>
In the first case, if the string were to contain something like
onclick=alert(document.cookie)
then your visitors would be
exposed to the malicious JavaScript.
The key is to know where your data comes from, and to act accordingly. Not all cases of the first example are necessarily a security hole, but it should only be used if you know the source and have validated your data beforehand.
public static quotes ($val)
Convert quotes to HTML entities for form input values. Note: This should only be done for trusted data, as it does not prevent XSS attacks.
Usage as a template filter:
{{ text|quotes }}
public absolutize ($val)
Absolutize a URL value.
Usage as a template filter:
<a href="{{ item->photo|absolutize }}">{{item->name}}</a>
public static autolink ($text)
Replace links in text with html links. For use as a template filter via:
{{ text|autolink }}
Note that you will likely want to sanitize your output too:
{{ text|sanitize|autolink }}
Or even add line breaks too:
{{ text|sanitize|autolink|nl2br }}
Based on: http://stackoverflow.com/a/1959073/1092725
private static add_parent_id ($data)
Clones and adds a parent_template_id value to the template data.
public replace_blocks ($regs)
Replace foreach and if blocks. Handles the following forms:
{% foreach some_list %}
{% endforeach %}
{% foreach some_list as key, item %}
{% endforeach %}
{% for some_list %}
{% endfor %}
{% for some_list as item %}
{% endfor %}
{% if statement %}
{% elseif statement %}
{% else %}
{% endif %}
Note: for
and endfor
are aliases of foreach
and endforeach
.
You can also use {% end %}
as an alias for {% endforeach %}
,
{% endfor %}
or {% endif %}
.
If an as
clause isn't specified, the current loop index is available
via {{ loop_index }}~ and the current loop value is available via
{{ loop_value }}`.
If an as
clause is specified without a key, the current loop index is available
via {{ loop_index }}
.
Template is a template compiler and rendering engine. It looks for templates via the pattern
apps/{app}/views/{file}.html
where the template is passed as'app/file'
. Failing that, it looks forlayouts/{file}.html
and finallylayouts/default.html
. It then creates a PHP version of the template and caches it tocache/{app}-{template}.php
, so the cache folder must be writeable. Auto-refreshes cached versions when the originals change.As a result, templates can include any PHP, along with tags of the form:
And blocks of the form:
Note the use of loop_index and loop_value, which are defined for you inside foreach loops by the template engine, or you can specify your own key and value names:
You can also test for more complex conditions, for example:
Note that
endif
andendforeach
are valid as well asend
, if you prefer, for the sake of clarity.Here's one more example of how to loop through an array of arrays:
To break up your template into smaller parts, you can use the
inc
tag to include one template from inside another. For example:This will include the contents of
layouts/header.html
into the current template, with the same data passed to it as the main template file.You can also specify subfolders in this way, to better organize your templates into themes. If you have a theme named
layouts/mytheme
then you can include aheader.html
template within it via:Note that this will first look for
apps/mytheme/views/header.html
, which would be the most frequently desired behaviour, and second it will look forlayouts/mytheme/header.html
, so be sure to name your themes with unique names that do not conflict with the names of apps.Usage in PHP
To call a template, use:
Note that arrays passed to templates are converted to objects, and objects are left as-is.
Globals
In addition to the fields in the data array passed to
render()
, you can also call global objects and class methods as follows from within if and foreach blocks as well as variable substitutions:Call User::constant_value:
Call $GLOBALS['user']->name:
Call a function:
In an if block:
In a foreach:
Calling a superglobal:
Note that these must come at the beginning of a statement, not anywhere else within it. The replacement mechanism is very simplistic.
Embedding handlers
You can use special
{! app/handler !}
tags to embed handlers directly into your templates. These are the equivalent of calling:You can also pass them an array of data using a shorthand like a url:
Or you can precompile them once when the template is compiled so the output of the handler is hard-coded into the template at compile time like this:
Filters
Filtering is supported, and
htmlspecialchars()
is the default filter unless another is specified or 'none' is supplied via:Any valid function can be a filter, and filters can be chained, executing in the following order:
This evaluates to:
You can also set additional parameters to a filter as follows:
Built-in filters include:
quotes
- Escape quotes as HTML entities for form input values. SeeTemplate::quotes()
.sanitize
- Sanitize output against XSS. SeeTemplate::sanitize()
.autolink
- Replace links in text with HTML links. SeeTemplate::autolink()
.absolutize
- Ensure a URL value is absolute. SeeTemplate::absolutize()
.comma
- Outputs the value followed by a comma only if the value is not empty.String translations
You can use the following tag format to mark strings for translation into the current visitor's language:
This will be replaced with a call to: