DoConure

Conditional parts

Four words — if, elseif, else, endif — and where you put the tag decides how much disappears.

{% if invoice.total > 1000 %}
  …this block…
{% elseif invoice.total > 500 %}
  …or this one…
{% else %}
  …otherwise this…
{% endif %}
Where the tag sitsWhat disappears
Alone in a paragraph The whole block between it and its endif. No blank line is left where the tags were.
Alone in a table cell The whole row. Put the opening tag in one row and the closing tag in another, with the rows to hide between them.
Inside a sentence Only those words: Dear {% if vip %}valued {% endif %}customer.

You no longer need the tr and p prefixes. They still work if you already use them — a tag you prefixed by hand is left exactly as written — but a plain {% if %} alone in a cell already hides the row.

What a condition may say

WriteTrue when
invoice.total > 1000 a number is bigger. Also <, >=, <=
customer.country = 'IT' the values match. Case is ignored, and '10' equals 10 — the same leniency as field merging
invoice.total != invoice.paid two of your own fields differ
order.status in ['shipped', 'delivered'] the value is one of a list
exists customer.vat the field was sent at all
empty notes the field is missing, blank, zero or an empty list
a and b · a or b · not a combined, with brackets where you need them

A field that was never sent makes a condition false rather than failing the document. So do 0, null, an empty string and an empty list — which is what {% if discount %} relies on.

A hidden section says why. When a condition comes out false, the generation records the reason with the value it saw — invoice.total (800) > 1000 is false — and it appears on the document's page in the console. That is usually the whole investigation.

Conditions outside the list above are still accepted and handed to the template engine as written; they simply cannot produce that sentence.