Conditions
Conditions make one template work for many situations. Show a discount section only when there is a discount, print text in the customer’s language, or produce a different layout depending on a choice in the configurator.
There are three kinds of conditions:
| Kind | Use it to | Example |
|---|---|---|
| Inline conditions | Print a word or value depending on a condition | Tilbud or Quote |
| Removing elements | Remove a table row, paragraph, table or image | Hide the discount table when there are no discounts |
| Conditional blocks | Show or hide a larger section of the document | Include a terms page only for export customers |
Comparison operators
Every condition starts with a comparison. It is applied to the value of the tag:
| Operator | Meaning | Example |
|---|---|---|
ifEQ(value) | equal to | {d.languageSlug:ifEQ('da')…} |
ifNE(value) | not equal to | {d.countrySlug:ifNE('DK')…} |
ifGT(value) | greater than | {d.conf_total:ifGT(100000)…} |
ifGTE(value) | greater than or equal to | {d.form_submissions[0].quantity:ifGTE(2)…} |
ifLT(value) | less than | {d.vat_total:ifLT(1)…} |
ifLTE(value) | less than or equal to | {d.revision_number:ifLTE(1)…} |
ifIN(value) | contains (text or list) | {d.email:ifIN('@example.com')…} |
ifNIN(value) | does not contain | {d.configuration_name:ifNIN('Draft')…} |
ifEM() | is empty (empty text, null, empty list) | {d.origin_request_id:ifEM()…} |
ifNEM() | is not empty | {d.extra_fields[0].fields[slug='warranty'].value:ifNEM()…} |
Inline conditions
Use show to print a text when the condition is true, and elseShow to print a text when it is false:
{d.languageSlug:ifEQ('da'):show('Tilbud'):elseShow('Quote')}{d.vat_total:ifGT(0):show('incl. VAT'):elseShow('excl. VAT')}{d.revision_number:ifGT(1):show('Revised quote'):elseShow('Quote')}Quoteexcl. VATQuoteWithout elseShow, the original value is printed when the condition is false. This is handy for fallbacks:
Payment terms: {d.extra_fields[0].fields[slug='payment'].value:ifEM():show('30 days net')}Several values (switch)
Chain several conditions to map values to texts:
{d.countrySlug:ifEQ('DK'):show('Denmark'):ifEQ('SE'):show('Sweden'):ifEQ('DE'):show('Germany'):elseShow('Other')}DenmarkShow another field
Use a path instead of a fixed text to print another field. A path starting with a dot is relative to the same object:
{d.user.name:ifEM():show(.email)}This prints the user’s name, or their email address if the name is empty.
Language-dependent text
Use languageSlug to translate static text in your template:
{d.languageSlug:ifEQ('da'):show('Gyldig til'):ifEQ('de'):show('Gültig bis'):elseShow('Valid until')}: {d.created_at:addD(30, 'day'):formatD('DD-MM-YYYY')}Request fields also contain translated labels in translation, for example translation.da_name. To switch a whole table between languages, wrap a Danish and an English version in conditional blocks:
{d.languageSlug:ifEQ('da'):showBegin} {d.extra_fields[0].fields[i].translation.da_name} {d.extra_fields[0].fields[i].value} {d.extra_fields[0].fields[i+1]}{d.languageSlug:showEnd}{d.languageSlug:ifNE('da'):showBegin} {d.extra_fields[0].fields[i].name} {d.extra_fields[0].fields[i].value} {d.extra_fields[0].fields[i+1]}{d.languageSlug:showEnd}Removing rows, paragraphs and tables
drop(element) removes the element that contains the tag when the condition is true. The tag itself prints nothing.
| Element | Removes |
|---|---|
row | The table row |
p | The paragraph |
table | The whole table |
img | The image |
col | The table column |
div, span | The element (HTML templates) |
keep(element) does the opposite: the element is kept only when the condition is true.
Hide empty request fields
Put the tag anywhere in the row. Rows without a value are removed:
| Terms | |
|---|---|
{d.extra_fields[0].fields[i].name} {d.extra_fields[0].fields[i].value:ifEM():drop(row)} | {d.extra_fields[0].fields[i].value} |
{d.extra_fields[0].fields[i+1]} |
Hide “No” answers
Configurators often contain yes/no questions such as Do you want to deselect the robot?. Remove those rows from a specification list:
| Element | Selection |
|---|---|
{d.form_submissions[0].form.data.elements[i].label} | {d.form_submissions[0].form.data.elements[i].options[i].label} {d.form_submissions[0].form.data.elements[i].options[i].label:ifEQ('No'):drop(row)} |
{d.form_submissions[0].form.data.elements[i].options[i+1]} | |
{d.form_submissions[0].form.data.elements[i+1]} |
You can get the same result with a loop filter: options[i, label!='No'].
Hide a table when it’s empty
Put the tag in any cell of the table, for example the heading row:
{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows:ifEM():drop(table)}The table is also removed when the Discounts table isn’t part of the BoM at all.
Hide a paragraph
If you have a request field with the slug reference, print the line only when it’s filled in:
Your reference: {d.extra_fields[0].fields[slug='reference'].value}{d.extra_fields[0].fields[slug='reference'].value:ifEM():drop(p)}Hide a missing image
When an option has no image, remove the image placeholder instead of showing an empty frame. Add both tags to the image’s alternative text:
{d.form_submissions[0].form.data.elements[i].options[i].image}{d.form_submissions[0].form.data.elements[i].options[i].image:ifEM():drop(img)}See Images, Links and Barcodes.
Remove several rows or paragraphs
Add a number to remove the element and the ones that follow it. This works for row and p:
{d.vat_total:ifEQ(0):drop(row, 2)}This removes the row with the tag and the next row, for example a VAT line and a total incl. VAT line.
Conditional blocks
To show or hide a larger part of a document, such as several paragraphs, tables and images, wrap it in showBegin and showEnd:
{d.form_submissions[0].form.data.elements[label='Quote Specification'].options[0].label:ifEQ('Seperate discount lines with prices'):showBegin}Discounts… discount table …{d.form_submissions[0].form.data.elements[label='Quote Specification'].options[0].label:showEnd}Everything between the two tags is included only when the condition is true. hideBegin and hideEnd do the opposite:
{d.vat_total:ifEQ(0):hideBegin}VAT: {d.vat_total:formatN(2)} {d.currencyCode}Total incl. VAT: {d.conf_total:add(d.vat_total):formatN(2)} {d.currencyCode}{d.vat_total:hideEnd}Layout switches from the configurator
A powerful pattern is to let the sales user choose the document layout in the configurator itself. The example quote has a Quote Specification element with the description “Based on what is chosen here, the pdf quote will generate differently”. Use its selected option to switch sections on or off:
{#spec = d.form_submissions[0].form.data.elements[label='Quote Specification'].options[0]}
{$spec.label:ifEQ('Seperate discount lines with prices'):showBegin}… table with every discount line and its price …{$spec.label:showEnd}
{$spec.label:ifNE('Seperate discount lines with prices'):showBegin}… only the total discount …{$spec.label:showEnd}Because the value comes from a form element, you can add new layout options in the Form Builder without touching the rest of the quote flow.
Combining conditions
Use and and or between comparisons. Without a parameter, the next comparison is applied to the same value:
{d.conf_total:ifGT(100000):and:ifLT(500000):show('Mid-size project')}{d.countrySlug:ifEQ('DK'):or:ifEQ('SE'):show('Nordic customer')}Pass a path to compare a different value. Use a path starting with . for a field on the same object, or a full d. path for any field in the data:
{d.conf_total:ifGT(100000):and(d.countrySlug):ifEQ('DK'):show('Free installation included')}{d.user.name:ifNEM():and(.email):ifNEM():show('Contact details available')}A full d. path is also the way to use a quote-level value, such as d.languageSlug, in a condition inside a loop.