Skip to content

Templates

Alexander Elchlepp edited this page Mar 28, 2026 · 12 revisions

Templates

This page documents the technical usage of the template editor in Settings → Templates.

Editor Modes

  • Visual Mode: WYSIWYG with toolbar, drag & drop snippets, and other format actions.
  • Code Mode: edit HTML/Twig directly (CodeMirror syntax highlighting + autocomplete).

Important: If you write complex Twig logic in Code Mode and then switch to Visual Mode, code can be removed. Visual Mode only preserves valid HTML structures.

Snippets

  • Snippets are shown in the left panel and can be inserted via drag & drop.
  • Available snippets depend on the selected template type.

Control Attributes for Simple Logic

Simple logic is represented with data-* attributes on HTML elements and transformed to Twig blocks on the backend before rendering.

Repeats

  • data-repeat="collectionPath"
  • data-repeat-as="itemVar"
  • optional: data-repeat-key="keyVar" (for key/value arrays)

Example outside a table:

<span data-repeat="miscPositions" data-repeat-as="position">
  [[ position.description ]]: [[ position.totalPrice ]] €<br>
</span>

Example inside a table:

<tr data-repeat="apartmentPositions" data-repeat-as="position">
  <td>[[ position.startDate|date('d.m.Y') ]]</td>
  <td>[[ position.totalPrice ]] €</td>
</tr>

Conditions

  • data-if="expression"

Example:

<tr data-if="address.company">
  <td>[[ address.company ]]</td>
</tr>

Pseudo-Twig Syntax

The system supports the existing placeholder syntax:

  • [[ ... ]] → expression
  • [% ... %] → block
  • [# ... #] → comment

Example:

[% for reservation in reservations %]
  [[ reservation.booker.lastname ]]
[% endfor %]

Code Mode Autocomplete

  • Autocomplete shows suggestions for variables when you are inside of [[ ]] or by using shortcut ctrl + space
  • Suggestions are type-aware (Entity, Collection, Array, Scalar, Date).
  • Selecting collection suggestions can generate a data-repeat block automatically.
  • date types are inserted with |date("d.m.Y")automatically

Header and Footer

All PDF types provide header/footer snippets (<div class="header">, <div class="footer">). Note: If a template would result in more than one PDF page, you should place the footer at the top of your template otherwise it will be visible only on the last page of the generated PDF.

Templates in Templates

Templates can be embedded into other templates and used as reusable building blocks. A typical use case is a shared footer based on TEMPLATE_FILE_PDF that is included in multiple PDF templates such as invoices or reservations.

Usage

  • Open the snippets sidebar and use the Templates section.
  • The sidebar only shows templates that are embeddable into the currently edited template.
  • Clicking or dragging an entry inserts a template include placeholder.
  • In Visual Mode, the include is rendered as a non-editable pill.
  • In Code Mode, the include is stored as HTML:
<span data-template-id="42" class="template-include">Footer</span>
  • During preview/rendering, the referenced template is resolved and replaced with its rendered content.

Compatibility Rules

  • TEMPLATE_FILE_PDF can be embedded into any template type.
  • All other template combinations require the same base type. Example: TEMPLATE_RESERVATION_PDF and TEMPLATE_RESERVATION_EMAIL are compatible with each other, but not with unrelated types.
  • Circular references are detected automatically.
  • Template includes are limited to a maximum nesting depth of 5 levels.

Template Types

Clone this wiki locally