TexturePacker & PhysicsEditor Template Language
TexturePacker templates have a syntax that is very similar to that of Django templates. If you are familiar with Django templates, then you will find TexturePacker templates to be very easy to learn.
Syntax of the templates
The syntax of templates contains four types of tokens:
- plain text
- comments
- variables
- control tags
A simple template might look like this:
{# A simple template example #}
Hello {{ person.name }},
{% if person.hasBirthday %}
Happy Birthday!
{% else %}
Have a nice day!
{% endif %}
Bye,
{{ myname }}
- Content inside
{# #}
are comments and are not part of the output. - Content inside
{{ }}
are variables which are substitued when the template is rendered. - Content inside
{% %}
are control tags which can affect the rendering of the template.
TexturePacker and PhysicsEditor both support commonly used tags such as if
, for
, cycle
and a
host of others (see https://docs.djangoproject.com/en/1.10/ref/templates/builtins/). It is also
possible for to define your their own tags.
Loops
The type of a variable determines how it can be used in templates. For example, treatment of items in an iterable context works as follows.
Lists work as expected:
{% for item in mylist %}
- {{ item }}
{% endfor %}
Truthiness
Truthiness of a variable is evaluated in a similar way to python. That is,
- an empty string is
false
0
isfalse
- an empty list is
false
- boolean
false
isfalse
Everything else is true
.
{% if mylist %}
List items:
{% for item in mylist %}
- {{ item }}
{% endfor %}
{% else %}
The list ist empty.
{% endif %}
Variable lookups
So far we've mostly used simple variable lookups in variable
tags,
but the template system is capable of a lot more. Complex structures can be evaluated using the dot (.
) character.
The dot can be used for list index lookup (Note that list lookup is 0
-indexed):
The first item is {{ mylist.0 }}, and the fifth item is {{ mylist.4 }}.
It can also be used for key lookups:
The hash value is {{ myhash.mykey }}.
And it can retrieve properties from an object instances:
The object property is {{ myobj.myprop }}.
Filters
Filters can further affect the result of including a variable in a template. Filters are separated by the pipe (|
) character.
Name is {{ name }}, and name in uppercase is {{ name|upper }}.
Which is rendered as
Name is Alice, and name in uppercase is ALICE.
Note that filters may be combined with dot-lookup. For example, if people
is a list of Person
objects,
and Person
objects have name
properties:
First persons name: {{ people.0.name|upper }}.
Rendered as
First persons name: BOB.
Filters may also be chained. Here, 'Claire' is first uppercased, then lowercased:
Name is {{ name|upper|lower }}
Rendered as
First persons name: claire.
Filters may take one string argument, which is delimited by a colon (:
).
If peoplestring
contains "Dave and Ellen and Frank"
, we can cut the string and
The people are {{ peoplestring|cut:"and " }}
Rendered as:
The people are Dave Ellen Frank.
Internal filters are:
upper
lower
slice
truncate
join
split
Also see https://docs.djangoproject.com/en/1.10/ref/templates/builtins/
Auto-escaping in templates
When creating HTML string output it is necessary to consider escaping data
inserted into the template. HTML escaping involves replacing <
with &lt;
and &
with &amp;
etc. The template engine automatically escapes string input before adding it to the output.
This is relevant when writing a variable from the context into the Template.
If the context object companies
is a list containing (Burger King
, Ben & Jerries
, Ford
),
and it is used in a template such as:
{% for company in companies %}
- {{ company }}
{% endfor %}
The output would be
- Burger King
- Ben & Jerries
- Ford
Notice that the &
has been replaced with &
, as is appropriate for html output.
Use the |safe
filter to get the un-escaped content of the string:
{% for company in companies %}
- {{ company|safe }}
{% endfor %}
It is also possible to turn this auto-escaping feature off for a block in a template.
For example:
{% autoescape off %}
...
{% endautoescape %}
would not escape the content between the autoescape
and endautoescape
tags. This should only be used for content
which is actually already safe.
Also see https://docs.djangoproject.com/en/1.10/ref/templates/language/#for-individual-variables
A better way to write exporters
We've created many of our first exporters using this template syntax but found it hard because the templates get quite unreadable if you want to create properly formatted output.
The newer exporters use a simple template like this for TexturePacker - here the Phaser exporter:
{% load phaser %}{{tp|exportData|safe}}
This practically disabled the template. All formatting is done in Javascript which is
way more readable - and, since we can use JSON.stringify
- always exports correct JSON data.
There's a file called grantlee/0.2/phaser.qs in the exporter that contains that code:
var exportTexture = function(...)
{
...
}
var exportData = function(root)
{
var doc = {
textures: exportTexture(root),
meta: {
app: "https://www.codeandweb.com/texturepacker",
version: "3.0",
smartupdate: root.smartUpdateKey
}
};
return JSON.stringify(doc, null, "\t");
}
exportData.filterName = "exportData";
Library.addFilter("exportData");