Compose your template

Overview

The templating system uses HTML and CSS, which together are the language of the world wide web.

  • HTML tags provide structure

  • CSS classes provide layout and design

  • Mail merge tokens allow for record substitution

  • Conditionals, loops and queries allow for powerful document composition

A template starts and ends with an <article> tag, within which you can use other HTML elements.

Mail merge tokens look like {$token}, and the list of available tokens are available from within the system and vary from register to register.

An example letter is as follows.

<article>
  <h1>My page heading</h1>
  <p>
    I am a paragraph with a <strong>set of bold words</strong>.
  </p>
  <p>
    Your name is {$personName}.
  </p>
</article>

Common HTML Elements

Also, you have HTML elements that can be used for semantic formatting — here’s the common ones.

HTML Element
Description

<article>

Used to define the overall page content

<address>

Used to hold the address content for windowed envelopes

<p>

A paragraph. Formatting can control the spacing and positioning of paragraphs.

<p>
  I am a paragraph.
</p>
<p>
  I am another paragraph.
</p>

<strong>

Boldfaced text

My name is <strong>Scott Davey</strong>

<em>

Italicised text (emphasis)

My name is <em>Scott Davey</em>

<ol>

Ordered list (e.g. numbered)

<ol>
  <li>Item one</li>
  <li>Item two</li>
  <li>Item three</li>
</ol>

Tip: these do not go inside paragraphs

<ul>

Unordered list (e.g. bullet points)

<ul>
  <li>Item one</li>
  <li>Item two</li>
  <li>Item three</li>
</ul>

Tip: these do not go inside paragraphs

<h1>, <h2>, <h3>

A page heading, a sub-heading and a small heading.

<h1>Special conditions</h1>

Tip: these do not go inside paragraphs.

<br />

A line break (e.g. a carriage return). These move the content

<p>
  Line 1<br />
  Line 2<br />
  Line 3<br />
</p>

<hr />

A page break.

<!-- This is a comment -->

Comments that do not appear in the output

Using conditions, loops and queries

The templating system contains powerful features for condition checking, loops and more.

Only include a paragraph if data exists for it

This shows how to conditionally include a heading and a paragraph based on the presence of text.

{if $specialNotes}    
    <h2>Special Instructions:</h2>    
    <p>{$specialNotes}</p>
{/if}

Adding a date

There are a few system build tokens that output dates.

Token
Description

{$MERGE_DATE}

The date which merge document has been generated.

{$MERGE_DATETIME}

The date and time which merge document has been generated.

{$IN_TWO_WEEKS}

The date 2 weeks from today.

{$IN_THREE_WEEKS}

The date 3 weeks from today.

{$IN_FOUR_WEEKS}

The date 4 weeks from today.

{$due}

Displays the date in the format of: 15/08/2021

This token is also useful f you have Process Workflow Updates on Items turned off for your template. If Process Workflow Updates on Items is turned off, it will still calculate what the due date will be and it will appear in the letter even though it doesn't update the item.

You can also create your own relative date from the current system date.

{"+35 days"|date_format:"%d-%m-%Y"}

Date formatting

The output of non workflow status date/time fields can be formatted using the date_format modifier.

{$item.datePermitDeclined|date_format:"%d-%m-%Y %l:%M %p"}

will output the date/time as 11-10-2021 5:00 PM

date_format conversion specifiers:

  • %a - abbreviated weekday name according to the current locale

  • %A - full weekday name according to the current locale

  • %b - abbreviated month name according to the current locale

  • %B - full month name according to the current locale

  • %c - preferred date and time representation for the current locale

  • %C - century number (the year divided by 100 and truncated to an integer, range 00 to 99)

  • %d - day of the month as a decimal number (range 01 to 31)

  • %D - same as %m/%d/%y

  • %e - day of the month as a decimal number, a single digit is preceded by a space (range 1 to 31)

  • %g - Week-based year within century [00,99]

  • %G - Week-based year, including the century [0000,9999]

  • %h - same as %b

  • %H - hour as a decimal number using a 24-hour clock (range 00 to 23)

  • %I - hour as a decimal number using a 12-hour clock (range 01 to 12)

  • %j - day of the year as a decimal number (range 001 to 366)

  • %k - Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)

  • %l - hour as a decimal number using a 12-hour clock, single digits preceded by a space (range 1 to 12)

  • %m - month as a decimal number (range 01 to 12)

  • %M - minute as a decimal number

  • %n - newline character

  • %p - either 'am' or 'pm' according to the given time value, or the corresponding strings for the current locale

  • %r - time in a.m. and p.m. notation

  • %R - time in 24 hour notation

  • %S - second as a decimal number

  • %t - tab character

  • %T - current time, equal to %H:%M:%S

  • %u - weekday as a decimal number [1,7], with 1 representing Monday

  • %U - week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week

  • %V - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week.

  • %w - day of the week as a decimal, Sunday being 0

  • %W - week number of the current year as a decimal number, starting with the first Monday as the first day of the first week

  • %x - preferred date representation for the current locale without the time

  • %X - preferred time representation for the current locale without the date

  • %y - year as a decimal number without a century (range 00 to 99)

  • %Y - year as a decimal number including the century

  • %Z - time zone or name or abbreviation

  • %% - a literal '%' character

Adding a photo

If your register contains an attachment field (e.g. a field where you can attach photos), then you can output the attached media into your PDF.

Most photo attachment fields are called media , but you can check your field reference for the exact name.

{foreach from=$media item="photo"}      
    <img class="media" src="{$photo}">
{/foreach}

We use {foreach} here because attachment fields can contain multiple attachments. This command says "loop over the $media field's contents, and for each file, call it $photo".

While this approach works, it will insert the photo at its full size, which is not ideal as it may produce large PDFs.

Resizing photos to reduce file size

To handle large images, you can replace your <img> tag with {thumbnail}, which resizes image first

{thumbnail class="media" file=$photo width=500 quality=50}

This will resize the photo to 500 pixels wide and quality 50, and then output it in an <img> HTML tag.

You can specify both height and width, or just one dimension. The system will fit the image to the specified dimensions and maintain image proportions.

Attribute
Description

file

The file object

width

The width in pixels. At least one of width or height is required.

height

The height in pixels. At least one of width or height is required.

quality

The quality in percent (default is 100)

class

Optionally set the HTML class of the <img> tag.

output

Optionally override the HTML output. See below for details.

crop

Set to fit or crop. Default is fit

forceUpsize

If the image is already smaller than the width/height then normally it will not be resized; if set to true then this forces it to be scaled up. Default is false.

The {thumbnail} height and width settings work in pixels (because it is resizing an image), while typical print styling of an <img> tag will want to be in millimetres. You can use class attribute to set the CSS class, or the output attribute to control the HTML output directly.

Experienced HTML authors may want an advanced way to control the output of the HTML, which can be done using the output attribute.

{thumbnail file=$photo width=500 quality=50 output="<img style='width:100px' src='%f'>"}

This example resizes replaces the default img tag output with something completely customisable, in this case, one with an inline style.

Adding a photos page if evidence exists

If we have any media attached to the record, this renders it on its own page.

{if $media}   
    <!-- Page break and carriage return to position heading -->  
    <hr />  
    <br />     
    
    <!-- Centre out heading -->  
    <h1 class="center-text">Evidence</h1>     
    <p>           
        <!-- Loops on all media, creating a {$photo} mail mege token for each photo -->    
        {foreach from=$media item="photo"}      
            <!-- The class of "media" makes it a comfy size for printing-->
            <!-- If you have large photo sizes, consider using {thumbnail} here -->
            <img class="media" src="{$photo}">    
        {/foreach}  
    </p>   
{/if}

Adding override fields to your letter

Some registers are configured with override fields, which if set, will override another default. Check your register's data dictionary for these fields; they will typically be called overrideXXX.

To use an override field, use an if statement as follows:

Property No.
{if $item.overridePropertyNumber}
   {$item.overridePropertyNumber}
{else}
   {$item.Asset.friendlyCode}
{/if}

The output of this will have the fixed words "Property No.", and then one of the two numbers.

Property No. 12345

Fire Prevention Notice Overrides

The Fire Prevention Notice register contains fields that override the default owner details, property number and location.

{$item.overrideLocation}
{$item.overridePropertyNumber}
{$item.overrideLocation}

Multiple Override Owner Details

You can add multiple override owners into the Override Owner Details section of your Fire Prevention Notice.

Each owner should be separated by a hyphen on a new line which will then generate separate letters for each override owner. Below is an example of how to add multiple override owners.

In this example two letters will be created, one for Fred Smith and one for Nathan Jones. The token {$overrideOwnerDetails} will automatically work with any multiple override owner details entered.

Using CQL in your if conditions

You can use the in_cql() function to construct an if condition based on an item matching a filter or CQL search term.

For example, the following checks whether the item is within a geospatial zone called frv :

{if in_cql($item, 'within:frv')}
   Display some text here for items within the frv zone
{else}
    Display some text here for items outside the frv zone
{/if}

As another example, this checks whether the item had the tag dogs added to it.

{if in_cql($item, "#dogs")}
  You have a dog
{/if}

See Searching and Filtering for details on the CQL query language.

Constructing a list from a series of checkboxes

If your form has a series of checkboxes, you can construct a list using <li> lists and {if} conditions:

<p>
    Remedy the following (your text here):
</p>
<ul>
    {if isset($item.createClearanceZone)}
        <li>Create a 4m wide by 4m high clearance zone along the driveway by lopping branches & trimming bushes to allow access for emergency service vehicles to your property </li>
    {/if}
    {if isset($item.createFirebreakBuildings)}
        <li>Create a firebreak around any buildings, structures, haystacks, flammable liquid store or derelict vehicles, to a maximum height of 100mm, The firebreak must have a minimum width of {$item.createFirebreakBuildingsMinWidth} </li>
    {/if}
    {if isset($item.createFirebreakPerimeter)}
        <li>Create a firebreak around the perimeter of the whole property, to a maximum height of 100mm. The firebreak must have a minimum width of {$item.createFirebreakPerimeterMinWidth}</li>
    {/if}
    {if isset($item.createFirebreakRoadside)}
        <li>Create a firebreak along the roadside boundary of your property, to a maximum height of 100mm. The firebreak must have a minimum width of {$item.createFirebreakRoadsideMinWidth} </li>
    {/if}
    {if isset($item.cutGrass)}
        <li>Cut all grass, weeds and undergrowth on the whole block, including fence line, to a maximum height of 100mm </li>
    {/if}
    {if isset($item.cutGrassFence)}
        <li>Cut all grass, weeds and undergrowth on the fence line, to a maximum height of 100mm </li>
    {/if}
    {if isset($item.maintainClear)}
        <li>The defined area must be cleared to the standard specified and maintained in this condition for the duration of the declared Fire Danger Period </li>
    {/if}
    {if isset($item.removeFuel)}
        <li>Remove excess fine fuel e.g. cut grass, leaves, bark, twigs from whole of property </li>
    {/if}
    {if isset($item.removeHeavyFuel)}
        <li>Remove or isolate excess heavy fuel e.g. branches, prunings, dead vegetation from whole of property</li>
    {/if}
    {if isset($item.removeMaterial)}
        <li>Remove all flammable materials, including wood, grass and other greenwaste, from around or overhanging your house, outbuildings or neighbours buildings, to a minimum distance of {$item.removeMaterialMinDistance}</li>
    {/if}
    {if isset($item.removeMaterialsProperty)}
        <li>Remove all flammable materials, including wood, grass, prunings and other greenwaste from the whole of the property</li>
    {/if}
    {if isset($item.removeWaste)}
        <li>Remove all accumulated general waste identified as a fire hazard (refer photos)</li>
    {/if}
    {if isset($item.attachMap)}
        <li>Conduct work as shown on the attached map</li>
    {/if}
</ul>

Last updated

Was this helpful?