Template Syntax
How do templates work?
Handshake's template system shares a similar syntax to Django's template language. If you have never encountered a templating system like this before, and you find Handshake's default templates confusing, take a few minutes to read Django's templating intro - it's well written and breaks down the basics very quickly.
Similar to Django, but not exactly the same
Handshake's template syntax is similar to Django's, however the engine is more simplified and cut-down and there are a few differences that you should be aware of:
- Block end-markers use a slash-prefixed syntax (
{% /if %}
,{% /for %}
) instead of Django'send
-prefixed syntax ({% endif %}
,{% endfor %}
). - Django's template system allows you to chain up multiple filters to modify variables prior to output, e.g.
{{ customer.name|upper|safe }}
. Handshake's templates support only a single filter on each variable. - Django's template system supports conditional expressions of an arbitrary number of terms, e.g. you can form expressions like
{% if a == b and c < d and e != f %}
. Handshake's conditionals are much more restricted and can be of at most two terms with an operator in-between, e.g.{% if a == b %}
or{% if condition1 and condition2 %}
. - Handshake's template filters allow you to join multiple lines of output together by leaving a backslash at the end of a line in the template. This is especially useful when writing CSV templates with many values on a single line, otherwise they can quickly stretch off the edge of your screen and become hard to read.
- Handshake supports a subset of Django's loop-inspection functionality. We support
{{ forloop.counter }}
to get the count-from-1 iteration of the current loop,{{ forloop.counter0 }}
to get the count-from-0 iteration of the current loop, and{{ forloop.parentloop }}
to get a reference to the enclosing loop if you have nested loops. - Handshake's templates do not have an explicit value for
null
/nil
/None
. If you want to test if a template parameter is null or undefined, you should usenot
, e.g.{% if not _param_name_ %}
.
Standard filters
The following standard filters can be applied to any variable in a Handshake template to modify it prior to output:
uppercase
,lowercase
, andcapitalized
can be used to transform the case of text.date
can be used to format a date as appropriate for the country you're in. You can also supply a custom date format after a colon, e.g.date:"yyyyMMdd"
. The full list of acceptable formats is described in the Unicode standard.format
can be used to apply printf()-style formatting. This can be useful for formatting numbers to a particular format, e.g.{{ 5 | format:'03d' }}
would give005
, or{{ 3.141592 | format:'.2f' }}
would give3.14
.currency
can be used to format a decimal number as currency, usually determined by the currency of the customer who is relevant in the current context.linebreaksbr
can be used to translate line breaks in text into<br/>
tags for HTML output.length
can be used to give the length of a string or list.csvsafe
can be used to format a variable in a format that is safe to use in a CSV file. This includes converting it to raw ASCII and escaping commas and other punctuation that will upset the format of the spreadsheet. You should pretty much use this on every value in a CSV template unless you're 100% sure it will be numeric every time.csvsafe_stripnewlines
is just likecsvsafe
except it also replaces all newlines with spaces. This is useful if your CSV parser doesn't correctly handle newlines inside quoted fields.slice
extracts a range from a string based on zero-indexed offsets, e.g.{{ 'hello world'|slice:'1:5' }}
would evaluate to "ello".split
splits a string on a separator and returns a zero-indexed substring from the split, e.g.{{ 'ABC-123-456'|split:'-:1' }}
would evaluate to "123", because that string is at index 1 after splitting on "-".
Math support
Handshake's templates support the five basic math operations add, subtract, multiply, divide, and negate. In each case, the values you use can either be variables (e.g. something like line.unitPrice
) or they can be numeric literals (e.g. 42
).
{% add x y %}
will calculatex + y
{% subtract x y %}
will calculatex - y
{% multiply x y %}
will calculatex * y
{% divide x y %}
will calculatex / y
{% negate x %}
will calculate-x
All math operations will round off to (at most) two decimal places and you can optionally include asCurrency
at the end of a math expression to format the result as currency, e.g. {% add 3.5 2.5 asCurrency %}
would evaluate to "£6.00" if you were selling in GBP.
At this stage, you cannot chain multiple math operations together, e.g. {% multiply {% add x y %} z %}
will not work and will not evaluate to (x + y) * z
. If you need to do this for some reason, please and we'll figure it out.
What data can I access from templates?
When a template is rendered, a set of variables is passed in that the template can access. Mostly, these variables represent objects from your database (e.g. orders, customers, addresses etc), but sometimes they are status flags or other indicators to help you render the right information (e.g. the onlyToCompany
variable in the order confirmation email can be used to suppress product and company logo images if you don't want to spam your order input desk with them).
For details on exactly what data is available on objects like orders and customers, please refer to the resources section of the web services API documentation, which gives a comprehensive breakdown of the fields and methods attached to each data type.
The parameters available to each template are detailed in the following pages.