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's end-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 use not, 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, and capitalized 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 give 005, or {{ 3.141592 | format:'.2f' }} would give 3.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 like csvsafe 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 calculate x + y
  • {% subtract x y %} will calculate x - y
  • {% multiply x y %} will calculate x * y
  • {% divide x y %} will calculate x / 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.

Recent Discussions

12 Jan, 2013 03:37 AM
12 Jan, 2013 12:54 AM
13 Dec, 2012 07:31 AM
12 Dec, 2012 10:55 AM
13 Dec, 2012 10:28 PM