Template syntax

This guide will cover the essentials of the templating language.

It provides special instructions how to merge your data into the resulting output.

The same template syntax can be used in Google Docs, LibreOffice, MS Word and HTML documents or in plain text.

The formatting capabilities of Doxey allows you to merge text, images, maps, tables or lists into your documents using data from any data source.

Variables

With variables you can merge data into the resulting document.

Variables may represent just a single word, a longer text, a date, a number, an image or even a list of values.

Let's say you want to create a personalized letter. Your static document may contain the greeting:

Hello Daniel!

Now you want to replace the name Daniel with a variable to be able to generate personalized letters for different contacts. Replacing the name with a variable is easy, just type

Hello ${name}!

Default values

If you are creating personalized letters that you want to send out to a bunch of your contacts, you may have a number of contacts where you only know the email address but not the name.

You can specify a default value that will be printed if the variable is not available. Simply specify this default value in round brackets just after the variable name:

Hello ${name(customer)}!

If the name variable is not set, you will find this in your document:

Hello customer!

Playground

If you remove the name from the data, the default value will be displayed instead.

Hello ${name(customer)}!
{
  "name" : "Daniel"
}

   

Formatting

Doxey comes with a number of renderers that will help you to format dates, numbers and strings and other data in the various ways.

To use a renderer simply enter the name of the renderer and optionally the renderer-specific format after the variable name:

${variable;renderer(format)}

The syntax of the format varies depending on the the renderer, but in most cases you just specify a number of options separated by a semicolon.

Let's see a few examples to see how this works:

Break text into multiple lines

If you want to wrap text into multiple lines, you can specify the wrap option in the text renderer.

If the variable address contains a text that looks like this:

1600 Amphitheatre Parkway,Mountain View,CA 94043

You can break the parts into different lines like using the wrap option with , as delimiter:

${contact.address;string(wrap=,)}

This will break the address into multiple lines:

1600 Amphitheatre Parkway
Mountain View
CA 94043

Playground

Adjust the address and the delimiter to change the resulting output.

Hey ${name},

We will send your order to:

${address;string(wrap=,)}
{
  "name" : "Larry",
  "address" : "1600 Amphitheatre Parkway,Mountain View,CA 94043"
}

   

Dealing with long text

If your variable may contain very long text you can limit the length of the text using the max parameter.

Let's say you have a variable called description containing long text like this:

This may become a very long text, a very very long text, it contains the description of an item

You can cut off the text after 20 characters by using the max parameter:

${description;string(max=20)}

This will print:

This may become a ve

To indicate that text has been cut off you can specify the ellipsis option:

${description;string(max=20;ellipsis=...)}

The specified characters get appended after the shortened text, so now you will get:

This may become a ve...

Convert text to upper- or lowercase

Use the string renderer if you want to print out variables in uppercase or lowercase letters only:

${name;string(uppercase)} - ${name;string(lowercase)}

If the name is Daniel this will print

DANIEL - daniel

Combining options

Of course you can combine all of the explained options.

Let's recap the long text example to see how this works. The variable description contains this longer text:

This may become a very long text, a very very long text, it contains the description of an item

You can now combine the different options like this:

${description;string(uppercase;wrap=, ;max=50;ellipsis=...)}

This will print out the description variable like this:

THIS MAY BECOME A VERY LONG TEXT
A VERY VERY LONG...

Check out the renderer reference for a full description of the formatting capabilities of the string renderer.

Playground

Adjust the parameters of the string renderers to see how it affects the result.

Hey ${name},

We will send your order to:

${address;string(wrap=,)}

${description;string(uppercase;wrap=, ;max=50;ellipsis=...)}
{
  "name" : "Larry",
  "address" : "1600 Amphitheatre Parkway,Mountain View,CA 94043",
  "description" : "This may become a very long text, a very very long text, it contains the description of an item"
}

   

Dynamic parameters

Let's say you are generating an HTML email or website and want to render a URL as a link. You can use the link renderer for that and use the text option to specify the clickable text that should be displayed in the generated document:

${myurl;link(text=Click me)}

If the text that you want to display should be taken from a variable instead of typing it right into the template, you can use dynamic parameters in the renderer options:

${myurl;link(text=$mytext)}

In this example the text that will be displayed in your document will be taken from the variable mytext and the target link will still be taken from the myurl variable.

Playground

Change the myurl and mytext variables in the Data tab to modify the output of the link renderer.

<h1>Visit us at</h1>
<h2>${myurl;link(text=$mytext;target=_blank)}</h2>
{
  "myurl" : "https://cloud.withgoogle.com/next18/sf/",
  "mytext" : "Google Next"
}

   

Conditions

Conditions are a powerful feature to create sophisticated documents. You can for example assemble documents by including paragraphs depending on conditions.

The easiest condition is to check if a variable is set and has a value that is not false.

Let us add some text to our document only if the contact is male:

${if male}Guess what? You are male!${end}

The text between the ${if ...} and the ${end} tag will only be printed if the male variable is present and is not false.

If you want to add some text if the condition is not met, you can use the ${else} tag:

Dear ${if male}Mr.${else}Mrs.${end} ${familyName}

It may look a little bit complicated, but if you have a closer look you should get what it means:

If the contact is male, it will generate Dear Mr. Smith if the contact is not male, it will generate Dear Mrs. Smith instead.

Doxey allows you to compare your variables to a fixed value.

Let's say you have a variable called country and you want to print different text snippets based on the value of the country variable, you can use an if statement like this one:

${if country="DE"}You are from Germany${end}
${if country="US"}You are from the United States${end}
${if !country="DE"}You are not from Germany${end}

Playground

${if country="DE"}You are from Germany${end}
${if country="US"}You are from the United States${end}
${if !country="DE"}You are not from Germany${end}
{
  "country" : "DE"
}

   

Conditions and formatting

You can use all formatting capabilities to create advanced conditions.

Let's say you have a variable called email with the value [email protected] and you just want to compare the domain name you can leverage the string renderer to do so:

${if email;string(fromAfterFirst=@)="gmail.com"}You are using GMail${end}

In this example the string renderer will give you the the part of the email after the @ character.

When formatting your variables you will find a number of options that will return either true or false. This makes them work in if-statements.

If you for example want to check if the variable age contains a number greater than 21 you can use this statement:

${if age;number(gt=21)}You are of legal age${end}

If you have a variable name with value Oliver Angermann and want to check if the last name starts with an A, you could combine the formatting options like this:

${if name;string(fromAfterLast= ;startsWith=A)}Last word starts with character A${end}

If you have a variable releaseDate with value 2018/04/03 and want to check if it is in the next year you can combine the output pattern yyyy to only compare the year part with the addYear and equals options:

${if appointment;date(op=YYYY;addYear=-1;equals=$now)}Release is next year!${end}

Nested conditions

By nesting conditions you can emulate AND and OR operators.

Let try to solve this problem: You are running your business in the EU and want to create an invoice for a European customer, so you have to add VAT only if the customer is a private customer.

You can use reverse charge if the customer is a company identified by a valid VAT number.

Let's assume you have integrated Doxey into your own shopping site and have provided the variables vatId and euCustomer:

${if euCustomer}
You are a European customer.
${if vatId}
Verified VAT ID is ${vatId}, you are liable for the tax (“Reverse charge”).
${else}
% VAT for private customers included.
${end}
${else}
You are from outside the EU.
${end}
{
  "euCustomer" : true,
  "vatId" : "DE1234567890",
  "vatRate" : 21
}

   

Lists

Variables may contain a list of named values.

If you for example are loading a Google Sheet you will find a variables containing the values for each column.

If you want to print the title of the first contact, you can write ${contacts[0].title}, to print the title of the third contacts, use a statement like this: ${contacts[2].title}

To access the last contact in the list, you can write ${contacts[last].title}. This feature may come in handy if you for example want to access the last row of a worksheet.

${contacts.length} will print the number of contacts loaded.

Number of contacts: ${contacts.length}

Name of first contact: ${contacts[0].name}
Name of second contact: ${contacts[1].name}
Name of last contact: ${contacts[last].name}
{
  "contacts" : [
    {
      "name" : "Daniel"
    },
    {
      "name" : "Olli"
    },
    {
      "name" : "Esther"
    },
    {
      "name" : "Alex"
    }
  ]
}

   

Loops

Doxey also allows you to iterate over the values by using the foreach keyword.

Let's assume we have a list of contacts with the fields name and email.

The first argument in the foreach statement is the variable that contains the list, in our example it is the variable contacts holding the list of contacts.

The second argument in the foreach statement is the iterator which will help us to access the fields of each contact in the loop.

In the example we will pick contact as name for the iterator, but you can pick an arbitrary name instead - just make sure that you are using this name when accessing the fields.

<ul>
${foreach contacts contact}
<li>${contact.name} - ${contact.email}</li>
${end}
</ul>
{
  "contacts" : [
    {
      "name" : "Daniel",
      "email" : "[email protected]"
    },
    {
      "name" : "Olli",
      "email" : "[email protected]"
    },
    {
      "name" : "Esther",
      "email" : "[email protected]"
    },
    {
      "name" : "Alex",
      "email" : "[email protected]"
    }
  ]
}

   

What if we want to print out all email addresses in a single line, separated with a comma? If we use an approach like this:

${foreach contacts contact}${contact.name}, ${end}

we end up with this result:

Daniel, Olli, Esther, Alex,

This looks good, except that we also have a comma at the end of the list.

How can we avoid this?

Loops with separators

Doxey provides a special feature that allows you to create loops with a separator like this:

${foreach contacts contact , }${contact.name}${end}

So you can enter a delimiter in the foreach construct. You can use a single or multiple characters as a delimiter.

In our case we use a comma followed by a blank. The result looks like this:

Daniel, Olli, Esther, Alex

This is exactly what we needed!

Wrap values

You specify characters that will be prepended or appended when rendering a variable:

${<h1>,title,</h1>}

If the variable title would contain Hello World this would generate:

<h1>Hello World</h1>

This is great if you are generating HTML documents, but may be useful in other cases as well.

Let's say you want to print

Hi!

for users with no given name set, but

Hi Daniel!

for users with a given name available.

If you simply use the statement Hi ${if name}! and your name is empty, you will end up with Hi ! which contains an unwanted space character. If you remove the space, you'd get HiDaniel! if the name is set - which is even worse.

You could solve the problem by using a condition:

Hi${if name} ${name}${else}${end}!

This expression would check if the name is set and only add a space if the name is present.

This is quite a long statement just to get rid of the space character and can be simplified by just using the following shortcut:

Hi${ ,name,}!

Putting it all together

<!-- Wrap name in bold tags and provide default value -->
<p>Hello ${,name(dear customer),}!</p>

<!-- Format the current date in short form -->
<p>We have received your order at ${date;datetime(op=short)}.</p>

<!-- Print all authors separated by comma -->
<p>You have ordered books from ${foreach authors author , }${author.name}${end}.</p>

<!-- Print section for each author... -->
${foreach authors author}
<p><b>${author.name}</b></p>
<table>
<tr><th width="200" style="text-align:left">Title</th><th>Published</th></tr>

<!-- ... and display all books by this author -->
${foreach author.books book}
<tr><td width="200">${book.title}</td><td style="text-align:left">${book.published}</td></tr>
${end}
</table>
${end}

{
  "name" : "Daniel",
  "date" : "2018-02-25T13:15",
  "authors" : [
    {
      "name" : "Arnon Grunberg",
      "books" : [
        {
          "title" : "Mit Haut und Haaren",
          "published" : "2012"
        },
        {
          "title" : "Tirza",
          "published" : "2006"
        }
      ]
    },
    {
      "name" : "Fjodor Michailowitsch Dostojewski",
      "books" : [
        {
          "title" : "Schuld und Sühne",
          "published" : "1864"
        },
        {
          "title" : "Die Brüder Karamasow",
          "published" : "1877"
        }
      ]
    }
  ]
}

   

Learn more

The following guides will cover the aspects of the templating language.

Questions and Feedback

If you have any comments on this page, feel free to add suggestions right to the Google document that we are using to create this site.

If you are not yet member of the Doxey community, please join now to get updates from our end or to provide feedback, bug reports and discuss with other users.

Last Updated: 03.01.20