Templates
Group-Office has a flexible template system supporting variables with filters and structural blocks. They are used for newsletters, reports, invoice templates etc.
Syntax
Variables
By default some variables are already present:
{{now|date:Y-m-d}} The current date time object. In this example a date filter is used.
{{system.title}} The title configured at System Settings -> General
{{system.url}} The URL to Group-Office configured at System Settings -> General
A variable is written like this:
{{contact.name}}
Custom fields
A custom field can be accessed like this:
{{contact.customFields.<DATABASE_NAME_OF_CUSTOMFIELD>}}
Some custom fields are stored with an ID. Like a select field for example. You can get the text like this:
{{contact.customFields.asText.<DATABASE_NAME_OF_CUSTOMFIELD>}}
Arrays
Arrays can be written like this:
{{contact.emailAddresses[0].email}}
You can also iterate arrays using an [each] block:
[each address in contact.addresses]
[if {{address.type}} == "billing"]
{{address.formatted}}
[/if]
[/each]
And filter arrays by property and only write first match using “eachIndex”:
[each emailAddress in contact.emailAddresses | filter:type:"billing"]
[if {{eachIndex}} == 1]
{{emailAddress.email}}
[/if]
[/each]
Assign
But this is probably the best way to handle the case where you prefer a type of address but just use the first if that’s not found. It uses [assign] to create a new variable. If it’s empty it will use the first address:
[assign address = contact.addresses | filter:type:"postal" | first]
[if !{{address}}]
[assign address = contact.addresses | first]
[/if]
{{address.formatted}}
Finding a contact with id = 1 using the “entity” filter with parameter “Contact” (Available entities in your instance can be found in the core_entity database table):
[assign contact = 1 | entity:Contact]
{{contact.name}}
Find the first linked contact:
[assign firstContactLink = someEntityVar | links:Contact | first]
{{firstContactLink.name}}
Using [assign] to do some basic math
Note that inside the [each] block we access total with parent.total:
[assign total = 0]
[each invoice in invoices]
<tr>
<td>{{invoice.number}}</td>
<td>{{invoice.date|date:d-m-Y}}</td>
<td>{{invoice.expiresAt|date:d-m-Y}}</td>
<td align="right">{{business.finance.currency}} {{invoice.totalPrice|number}}</td>
<td align="right">{{business.finance.currency}} {{invoice.paidAmount|number}}</td>
[assign balance = {{invoice.totalPrice}} - {{invoice.paidAmount}} ]
[assign parent.total = {{parent.total}} + {{balance}}]
<td align="right">{{business.finance.currency}} {{balance|number}}</td>
</tr>
[/each]
{{business.finance.currency}} {{total|number}}
More examples
An advanced example for printing a custom salutation (Just an example. You can use {{contact.salutation}}):
Dear [if {{contact.prefixes}}]{{contact.prefixes}}[else][if !{{contact.gender}}]Ms./Mr.[else][if {{contact.gender}}=="M"]Mr.[else]Ms.[/if][/if][/if] {{contact.lastName}}
A simple example template:
Hi {{contact.salutation}},
Best regards,
{{creator.displayName}}
{{creator.profile.organizations[0].name}}
{{creator.profile.phoneNumbers[0].number}}
Attachment field with photo’s in e-mail template:
[each photo in contact.customFields.Photos]
<h3>{{photo.name}}</h3>
<img src="{{photo.blobId|blobUrl}}" alt="{{photo.name|htmlEncode}}" style="max-width:100%"><hr>
[/each]
Or photo’s from the entity’s files folder:
[each photo in document|entityFiles]
<h3>{{photo.name}}</h3>
<img src="{{photo.blobId|blobUrl}}" alt="{{photo.name|htmlEncode}}" style="max-width:100%"><hr>
[/each]
Filters
You can use filters to format data. They can be used with a “|” char followed by the filter name. Optionally the filter can take arguments separated by a “:”.
date(format as in PHP):
{{contact.dates[0].date|date:d-m-Y}}
number(decimals,decimal separator,thousands separator:
{{contact.customFields.number|number:2:,:.}}
multiply(multiplier): Multiply a number:
{{contact.customFields.number|multiply:2}}
add(number): Add to a number:
{{contact.customFields.number|add:2}}
entity(type, id): Fetch an entity by ID:
[assign contact = 1 | entity:Contact]
links(entityName, properties (comma separated): gets the linked entities:
[assign firstContactLink = someEntityVar | links:Contact | first]
prop(property) get a property from an object or array by name:
[assign formattedAddress = contact.addresses | sort:type:"postal" | first | prop:formatted]
nl2br: Change line breaks to HTML <br> tags
empty: returns true if empty or false if not
dump: For debugging only. Dumps the variable type and value.
Arrays
filter(property, value): Filters the array by property values:
{{contact.addresses | filter:type:"postal" | first}}
sort(property, value?) or rsort:
[assign formattedAddress = contact.addresses | sort:type:"postal" | first | prop:formatted] {{formattedAddress}}
count
first: Grab the first item of the array
prop(property): change the array to a sub property of all items.
implode(glue = ‘, ‘): Implode an array of strings:
{{contact.emailAddresses | prop:email | implode}}