Using if else condition in docx template

Certified Lead Developer

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

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    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! 

  • 0
    Certified Lead Developer
    in reply to gayathris876948

    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

  • 0
    Certified Lead Developer

    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.

  • 0
    Certified Lead Developer
    in reply to Shubham Aware

    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.

  • 0
    Certified Lead Developer
    in reply to ghanashyam905071

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

  • 0
    Certified Lead Developer
    in reply to ghanashyam905071

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