You are reading the documentation for an outdated Corteza release. 2023.9 is the latest stable Corteza release.

Templates

Templates allow you to define the generic document structure (such as a welcome email message or a quote PDF), which is then converted into an actual document based on the provided data.

If you wish to learn more about a specific topic, refer to the subsections under Low-Code Platform Developer Guide  Templates.

Creating a template

Templates are created and managed in the Corteza Admin.

Navigate to the System  Templates and click on the New button in the top-right corner.

Enter the basic information; short name, handle, description, and template type. The template type determines the template format and implicitly implies what document types the template can render to.

A partial template is used as part of another template (for example, a generic header or a footer) and can not be rendered independently. You can convert the template from and to a partial template.

Click on the Submit button to prepare your template.

After you submit the base parameters, three new sections will appear.

Toolbox

The toolbox provides snippets for the most common operations, HTML template sample, and partial inclusion samples.

Template content

The template content editor provides a simple code editor to edit your template. The HTML template editor implements syntax highlighting and some other useful tools.

Preview

The preview section allows you to test how your templates will look when rendered into an actual document.

The content

Advanced users are welcome to checkout the plain text template full reference, the html template full reference, and the extended function docs.

Let’s start by copying the default HTML sample from the toolbox.

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <title>Title</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>

If you don’t need any dynamic content (different name for different contacts), you can stop. The above template is valid and can already be used.

If you need dynamic content, we need to cover a few more topics.

Value interpolation

Value interpolation allows you to define some placeholder that is then replaced with an actual value when the template is rendered.

In our case, this placeholder looks like this:

{{.name}}

The value will replace the above placeholder under the name property from the provided value object.

Let’s look at some examples. Each example firstly defines the value object and then the placeholder.

Example with a basic property:
{
  "name": "Jane"
}

{{.name}}
Example with a nested property:
{
  "contact": {
    "details": {
      "name": "Jane"
    }
  }
}

{{.contact.details.name}}

A complete example would look like this:

The provided data:
{
  "contact": {
    "details": {
      "firstName": "Jane",
      "lastName": "Doe"
    }
  }
}
The template:
<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <title>Title</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
  <h1>Hello, {{.contact.details.firstName}} {{.contact.details.lastName}}!</h1>
</body>
</html>

Conditional rendering

Conditional rendering allows you to show or hide sections of the rendered document based on the input parameters.

if statement:
{{if condition}}
  The condition was true.
{{end}}
if-else statement:
{{if condition}}
  The condition was true.
{{else}}
  The condition was false.
{{end}}
if-else if-else statement:
{{if condition}}
  The condition was true.
{{else if condition}}
  The other condition was true.
{{else}}
  Neither conditions were true.
{{end}}

The condition part is an expression that returns a single boolean value. An example of an expression:

{{if .lead.cost > 1000}}
  The lead {{.lead.name}} was expensive!
{{end}}
Table 1. Logic operators:

AND

  • syntax: a && b

  • notes: Results as truthy if both a and b evaluate to true.

OR

  • syntax: a || b

  • notes: Results as truthy if either a or b evaluates to true.

NOT

  • syntax: !a

  • notes: Results as truthy if a is false and vice-versa.

Equal

  • syntax: a == b

  • notes: Results as truthy if a is equal to b.

Not equal

  • syntax: a != b

  • notes: Results as truthy if a is not equal to b.

Less then

  • syntax: a < b

  • notes: Results as truthy if a is less then b.

Greater then

  • syntax: a > b

  • notes: Results as truthy if a is greater then b.

Less equal then

  • syntax: a <= b

  • notes: Results as truthy if a is less or equal to b.

Greater equal then

  • syntax: a >= b

  • notes: Results as truthy if a is greater or equal to b.

Handling lists

Our templates make it quite easy to work with lists of items. For example, you would like to generate a quote with lots of line items.

The syntax for iterating over a list looks like this:

{{range .listOfItems}}
  {{.itemName}}; {{.itemCost}}$
{{end}}

If you prefer to specify what variable the current item is stored into, use this syntax:

{{range $index, $item := .ListOfItems}}
  {{$item.itemName}}; {{$item.itemCost}}$
{{end}}

Using functions

Sometimes you will need to process the data further before it is rendered to the document.

Some lighter processing can be handled directly by the template engine. More complex processing should be handled by the code that is requesting to render the template.

A function is called like this:
{{functionName arg1 arg2 ... argN}}

The passed argument can be a constant or a property from the provided data.

You can also chain functions. When two functions are chained, the left function’s output is passed into the argument of the right function.

{{funcA | funcB | ... | funcN}}
Table 2. Most common function reference:

Length of

  • syntax: {{len listOfThings}}

  • notes: returns the number of items in the given listOfThings.

Format string

  • syntax: {{printf "pattern goes here" arg1 arg2 …​ argn}}

  • notes: returns the formatted string, following the provided pattern using the values provided as arguments.

Inline remote file

  • syntax: {{inlineRemote "url goes here"}}

  • notes: returns the base64 encoded file denoted by the URL. The string is formatted in the form of data:{mime-type};base64,\{encoded remote file}. Useful when attaching images to PDF documents.

Trim string

  • syntax: {{trim "string goes here"}}

  • notes: removes any spaces from the start/end of the provided string.

Trim suffix from a string

  • syntax: {{trimSuffix "suffix to remove here" "string goes here"}}

  • notes: removes the suffix from the given string.

Trim prefix from a string

  • syntax: {{trimPrefix "prefix to remove here" "string goes here"}}

  • notes: removes the prefix from the given string.

To uppercase

  • syntax: {{upper "string goes here"}}

  • notes: converts string to upper case.

To lowercase

  • syntax: {{lower "string goes here"}}

  • notes: converts string to lower case.

Using partials

Partials allow you to keep your documents consistent by using common headers and footers. Partials can also be useful when displaying Cortezas' resources, such as displaying a record in a table.

Partials are included like so:
{{template "partial_handle"}}

The partial_handle is the handle you used when you defined the partial. For example:

{{template "email_general_header"}}

If your partial needs to access some data that you provided to the current template (the one that uses the partial), you need to provide the second argument to the partial inclusion process.

{{template "email_general_header" .property.to.pass}}

For example, if our data looks like this:

{
  "contact": {
    "values": {...}
  },
  "account": {
    "values": {...}
  }
}

If you want to pass the contact to the partial, you would include your partial like so:

{{template "partial_handle" .contact}}

If you wanted to pass all of the data to your partial, you would include your partial like so:

{{template "partial_handle" .}}

You would access the contact in your partial like so:

{{/* In case of the first example */}}
Hello {{.values.FirstName}}

{{/* In case of the second example */}}
Hello {{.contact.values.LastName}} of the {{.account.values.Name}}

The preview

The preview section at the bottom of the page allows you to check how your documents will look like once the template is rendered.

The input box should contain a valid JSON object (render payload) with two root properties; variables and options:

{
  "variables": {},(1)
  "options": {}(2)
}
1 The variables parameter defines what data will be available when rendering the document. The structure is not defined.
2 The options parameter defines the rendering options and is currently only available for PDFs.
An example of the render payload:
{
  "variables": {
    "param1": "value1",
    "param2": {
      "nestedParam1": "value2"
    }
  },
  "options": {
    "documentSize": "A4",
    "contentScale": "1",
    "orientation": "portrait",
    "margin": "0.3"
  }
}
Table 3. Complete render payload reference:

variables

  • type: Object<any>

  • description: the variables you wish to apply to the template. For example, if you wish \{{testing}} to work, you must pass {"variables": {"testing": "some value"}}.

options.marginBottom

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the bottom of the page.

options.marginLeft

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the left of the page.

options.marginRight

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the right of the page.

options.marginTop

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the top of the page.

options.marginY

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the top and bottom of the page.

options.marginX

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the left and right of the page.

options.margin

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: controls the margin on the left, right, top, and bottom of the page.

options.documentSize

PDF only.

  • type: string<A0…​A10, B0…​B10, C0…​C10, ANSI A, ANSI B, ANSI C, ANSI D, ANSI E, junior legal, letter, legal, tabloid>

  • description: The size of the document following the ISO216 standard for the A, B, and C series; ANSI standard for ANSI A, B, C, and D; and NA standards for the last few.

options.documentWidth

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: specifies the document width if none of the presets fit your needs.

options.documentHeight

PDF only.

  • type: string< float; 0 >= n; inches >

  • description: specifies the document height if none of the presets fit your needs.

options.contentScale

PDF only.

  • type: string< float; 0 >= n >

  • description: at what scale the document should be rendered; bigger number ⇒ bigger content.

PDF documents are limited to 0 >= n <= 8

options.orientation

PDF only.

  • type: string<landscape,portrait>

  • description: what orientation to render the document in.