4.3. The anatomy of a simple template

This section introduces all the concepts you must know to create or edit templates. You can use the ideas presented here to build any type of templates: Microsoft Word 2007, OpenDocument, HTML, XML, etc. To keep things simple, the templates from this section are plain text files.

When dealing with templates, there are three important concepts you need to know:

  • placeholders help you access fields like invoice number or invoice total,

  • built-ins can give more details about certain fields like the text representation for a date field and

  • directives which allow you to perform operations on fields like deciding what to do if an invoice has or doesn't have expenses.

Although templates can be used for several types of documents, we'll only focus on invoices here. We'll build an invoice template step by step to show all the concepts. The final template is in the file text-invoice.txt.

4.3.1. Placeholders or how to access fields

Let's suppose you create an invoice that has the number INV-23 and a total of USD 100. A possible layout for the invoice document could be:

INVOICE

Number: INV-23
Total: USD 100

Thank you for your business!

The number and total are emphasized to show that they are different for each invoice.

Fanurio can help you create invoices that have the same layout but it needs to know which parts of the document change and which don't. It does this with the help of a template.

Here's how the template for the above invoice looks like. It is similar to the actual invoice but the changing parts INV-23 and USD 100 have been replaced by ${invoice.number} and ${invoice.total}.

INVOICE

Number: ${invoice.number}
Total: ${invoice.total}

Thank you for your business!

When Fanurio exports an invoice using a template, it identifies all texts of the form ${...} as changing parts and replaces them with actual values. If the invoice number is a changing part, you use invoice.number inside ${...}. The text invoice.number is a placeholder for the actual invoice number.

Just like invoice.number, there are many other placeholders for the fields of an invoice, your business and your client's business. The complete list of placeholders can be found here.

This template is saved in the file text-invoice-01.txt.

Extra: You may also want to try other placeholders like your business contact details:

Supplier: ${business.name}
Address: ${business.address}

INVOICE

Number: ${invoice.number}
Total: ${invoice.total}

Thank you for your business!

4.3.2. Built-ins or how to get more details about a field

Usually, when you want to get the value of a placeholder, you put it inside ${..}. For some placeholders, you can also use built-ins to get additional details. A list of all built-ins can be found here.

For instance, date placeholders can use the ?date built-in to display them using the default format. The invoice.date placeholder represents the date when the invoice was issued. To access its value, you should use ${invoice.date?date}.

If we want to display the invoice date, the previous template changes to:

INVOICE

Number: ${invoice.number}
Date: ${invoice.date?date}

Total: ${invoice.total}

Thank you for your business!

This template is saved in the file text-invoice-02.txt.

Extra: Another built-in that can be used with dates is ?string. The following code displays the date in a user-specified format:

${invoice.date?string("yyyy-MM-dd")}

where yyyy is the year, MM is the month and dd is the day. Of course, you can change their order however you like.

4.3.3. Directives or how to perform operations on fields

Placeholders are usually not enough if you want to create an invoice template. You will also need to perform various operations on placeholders. We call these operations directives.

Some common directives are:

  • list

  • if

The list directive allows you to access placeholders with multiple values while if lets you make decisions based on the value of a placeholder. A list of all directives can be found here.

The list directive

The placeholders we've seen so far (invoice.number, invoice.total, invoice.date) are single-valued but there are placeholders that contain multiple values. The values of these placeholders cannot be simply accessed by surrounding them with ${...}, you have to access them element by element.

Let's suppose you want to display all the items of an invoice like this:

INVOICE

Number: INV-23
Date: Jan 01, 2001

Service1 5 x $10 = $50
Service2 2 x $5 = $10
Product1 1 x $10 = $10
Expense1 1 x $40 = $30

Total: USD 100

Thank you for your business!

where each emphasized line represents an item as:

name quantity x unit price = total 

The following template shows how you can use the list directive to display each invoice item on a separate line.

INVOICE

Number: ${invoice.number}
Date: ${invoice.date?date}

[#list invoice.items as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

Total: ${invoice.total}

Thank you for your business!

The invoice.items placeholder contains a list with all the items of an invoice. To access each item from this list you need to use the list directive. The list directive is always of the form:

[#list multi-value-placeholder as element]
access the element
[/#list]

In our example, the multi-value placeholder is invoice.items.

This template is saved in the file text-invoice-03.txt.

The if directive

Suppose that instead of displaying all items together, you want to group them by their type. One group for service items, one for product items and the another for expense items. The previous list:

Service1 5 x $10 = $50
Service2 2 x $5 = $10
Expense1 1 x $10 = $10
Expense1 1 x $30 = $30

becomes:

Services
Service1 5 x $10 = $50
Service2 2 x $5 = $10

Products
Product1 1 x $10 = $10

Expenses
Expense1 1 x $30 = $30

The template that makes this possible looks like this:

Services
[#list invoice.serviceItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

Products
[#list invoice.productItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

Expenses
[#list invoice.expenseItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

As you can see, we use not one but three list directives. One for the invoice.serviceItems placeholder, another for the invoice.productItems placeholder and the another one for the invoice.expenseItems placeholder. These three placeholders help us access items by their type (service, product or expense).

Let's take this example even further and assume that the list of expense items is empty. In that case, the invoice is:

Services
Service1 5 x $10 = $50
Service2 2 x $5 = $10

Products
Product1 1 x $10 = $10

Expenses

Since there are no expense items, you'll probably want to hide the "Expenses" text too. In other words, you want to display it only if there is at least one expense item. This can be done using the if directive as follows:

Services
[#list invoice.serviceItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

Products
[#list invoice.productItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]

[#if invoice.expenseItems?size != 0]
Expenses
[#list invoice.expenseItems as item]
${item.name} ${item.quantity} x ${item.price} = ${item.total}
[/#list]
[/#if]

The if directive wraps the text that is displayed conditionally. The text invoice.expenseItems?size != 0 is the condition that is interpreted as "number of expense items is different from zero". This condition evaluates to:

  • true if there is at least one expense item. In this case, the Expenses text together with all expense items are displayed.

  • false if there are no expense items. In this case, nothing is displayed.

Notice the ?size built-in. It applies to multi-value placeholders and retrieves the number of elements.

This template is saved in the file text-invoice-04.txt.