Skip to main content
May 22, 2026
Question

Using if else condition in docx template

  • May 22, 2026
  • 7 replies
  • 0 views

Hi Champs,

I am using docx from dynamic template smart service to create dynamic document. It's working with simple table. Now I want to try with if else condition in my template. I am not sure the syntax to use to work with it.Can someone please guide how to do it if we have if/else condition .

Regards,

Shyam

7 replies

gayathris111098
May 22, 2026

Hi Shyam,

Since your simple table is already working, here’s a complete guide for the next level — dynamic table rows, conditional rows, and lists — all using FreeMarker inside MergeFields.

1. Loop through a list to generate table rows ([#list])

In your Word template, create a table with a header row and one data row. Put the loop directives in that data row as MergeFields:

|# |Name |Status |
|-------------------------------------|-----------------|-------------------|
|`«[#list doc.project.items as item]»`| | |
|`«${item.@id}»` |`«${item.@name}»`|`«${item.@status}»`|
|`«[/#list]»` | | |

Each directive ([#list], [/#list]) must be its own separate MergeField in the cell. When looping over a list of XML elements, you don’t need a counter — just refer to each field using item.@fieldName syntax. 

2. Condition inside a table cell

To show different values per cell based on a condition:

«[#if item.@status == 'APPROVED']»Approved«[#else]»Pending«[/#if]»


Each part — the [#if ...], the text content, the [#else], and the [/#if] — must be placed as separate MergeFields. The text between them is plain Word text with formatting applied normally. 

3. Show/hide an entire table row conditionally

Put the [#if] MergeField in the first cell of the row and [/#if] in the last cell:

| «[#if item.@type == 'INTERNAL']» | «${item.@name}» | «${item.@value}» | «[/#if]» |

This hides the entire row when the condition is false.

4. Null / empty check for table cells

Use ?has_content to safely handle empty values:

«[#if item.@remarks?has_content]»«${item.@remarks}»«[#else]»-«[/#if]»


5. Row number / counter inside a loop

FreeMarker provides a built-in counter variable item_index (0-based):

«${item_index + 1}»


6. Notes

• Every [#list], [/#list], [#if], [#else], [/#if] must be in its own MergeField — never mixed with text.
• Use single quotes for string comparisons to avoid Word escaping double quotes to \".
• Check Appian System Logs for the full FreeMarker error — it pinpoints the exact line and column.

Hope this helps! 

May 22, 2026

I tried with the if syntax given as a separate merge field as sugegsted.. but during run time when I am using r.age > 30, it's throwing exception saying left hand operator is an extended node+sequence+hash+string

gayathris111098
May 25, 2026

Try <#if r.age?number > 30>
...
</#if>

shubhama926776
May 23, 2026

Pre-compute the flag in expression (ageAbove30: if(r.age > 30, "true", "false")) and pass it in your XML/dictionary.
In the template, use: «[#if r.ageAbove30 == 'true']»Above 30«[#else]»30 or below«[/#if]»

Each [#if], [#else], [/#if] must be its own separate MergeField.

May 25, 2026

I tried the same  «[#if r.ageAbove30 == 'true']»Above 30«[#else]»30 or below«[/#if]» but r.ageAbove30 is not taking as a boolean ; rather as an extended node+sequence+string and due to the same it's giving the error saying can't compare value of these types.

shubhama926776
May 25, 2026

Try this once
«[#if r.@ageAbove30?string == 'true']»Above 30«[#else]»30 or below«[/#if]»