How to use IF Condition in MS Word Mustache Template

I am unable to get the IF statements to work in my mustache templates using the Nodejs SDK. If I place something like this in my template:

{ IF “{{ GENDER }}” = “MALE” “true text” “false text” }

The if statement is not evaluated, and the output looks like this:

 { IF “MALE” = “MALE” “true text” “false text” }

Instead of this:

true text

I have reviewed the documentation https://docs.aspose.com/words/net/mail-merge-template-from-mustache-syntax/ and read a number of forum posts, but can not find a working example. (Several of the forum posts have links to download files that are broken.). The documentation references a setting “UseNonMergeFields” that I am not finding in the Nodejs SDK.

Could you please provide a working example in javascript that includes both the template and json files? The most common case we will need to support is just checking if a field has a value so we know whether to display it (so there are no extra lines in the document.)

@danobri

Please find a sample template along with the data. Please also check the cleanup parameter to remove empty paragraph unused regions/fields etc.

demoIf.zip (11.1 KB)

Looks like you provided data and output, but no template or code. Also - the output looks like it’s only partially evaluated…

Could you also provide an example using the cleanup parameter to remove empty fields, as I have tried that and it also did not work. Here is what I tried:

const mailMergeRequest = new ExecuteMailMergeOnlineRequest({
    template: fs.createReadStream(requestTemplatePath),
    data: fs.createReadStream(requestDataPath),
    cleanup: "UnusedFields"
});

I shared the templatedemoIf.docx (14.0 KB)
and sample JSON data above, here is the output documentTestIFElse.docx (11.4 KB)
for reference using following code.

const mailMergeRequestRegion = new ExecuteMailMergeOnlineRequest({
            template: mailMergeRequestResult.body,
            data: fs.createReadStream(localDataFile),
	    withRegions: true
		});
    wordsApi.executeMailMergeOnline(mailMergeRequestRegion)

@danobri

It seems you are using cleanup correctly. Please share your template and data file along with the expected sample output document for investigation.

Please also check the sample code to use multiple cleanup options.

const request = new ExecuteMailMergeOnlineRequest({
            template: fs.createReadStream(localDocumentFile),
            data: fs.createReadStream(localDataFile),
	    withRegions: true,
	    cleanup: "UnusedRegions,UnusedFields,RemoveTitleRow,RemoveTitleRowInInnerTables" 	
		});

I don’t see any IF statement in the template file?? Column b just has “false text” in it.

Mystery solved. I did not realize Aspose is requiring Word field codes for conditional statements. It does not say that in the documentation. Once I toggled field codes I could see the IF statement.

1 Like

The cleanup parameter is not working with the template I am using. Sample template and json are attached - the adressLine2 and addressLine3 fields in the header are displaying empty rows. Archive.zip (20.7 KB)

@danobri

We are sorry for the inconvenience, the EmptyParagraphs cleanup option is not working as expected. We have logged a ticket(WORDSCLOUD-1751) for further investigation and rectification. We will notify you as soon as it is resolved.

Isn’t UnusedFields the cleanup parameter that should be removing the empty lines in this example?

@danobri

The UnusedFields option removes the empty/unused fields but does not remove the empty paragraphs. So we have logged the above ticket to investigate the issue further.

Thanks - although I’m not understanding what you would use UnusedFields for - if the fields are empty, isn’t the output of the merge empty anyway?

@danobri

Please note Field and Paragraph are different node types in the Document Object Model(DOM) of Word document. So different Cleanup Options are used for these.

The issues you have found earlier (filed as WORDSCLOUD-1751) have been fixed in this update. This message was posted using Bugs notification tool by Ivanov_John

@danobri

About WORDCLOUD-1751, we have investigated your shared template and noticed it has some problems.

  1. We use hierarchical data therefore we need to use regions. All fields outside regions are ignored and aren’t processed (including removing them in the cleanup phase). So we need to add a start {{#foreach coverageChange}} and a final {{/foreach coverageChange}} that wrap all the fields.
  2. Start and end of the template must be on the same level. The template violates the rule. Some fields are on section level (they are inside a section header) and some fields are on the paragraph level. So we need to move all fields inside a section. After these changes, the resulting template is processed correctly and all cleanup options are applied to them. Please remember that we need to set withRegions to true.

The template is attached for reference.FixedCoverageChangeTemplate.docx (22.7 KB)

I actually process the template twice - once setting withRegions = false and once setting withRegions = true. I took the 21.12.0 update, and it did not fix the issue - even using the template you provided.
That said - wrapping the entire document in a foreach is not an option, as it makes no sense in this context - the data is a single record.

Here is the code I am running for reference:

const wordsApi = new WordsApi(clientId, secret);

let requestTemplatePath = "templates/FixedCoverageChangeTemplate.docx";
let requestDataPath = "data/coverageChange.json";
let outputPath = "output/coverageChange.pdf";

const mailMergeRequest = new ExecuteMailMergeOnlineRequest({
    template: fs.createReadStream(requestTemplatePath),
    data: fs.createReadStream(requestDataPath),
    cleanup: "EmptyParagraphs,UnusedRegions,UnusedFields,RemoveTitleRow,RemoveTitleRowInInnerTables", 
withRegions: false
});

wordsApi.executeMailMergeOnline(mailMergeRequest)
.then((mailMergeRequestResult) => {
    console.log("merge complete");
    const regionMergeRequest = new ExecuteMailMergeOnlineRequest({
        template: Readable.from(mailMergeRequestResult.body), 
        data: fs.createReadStream(requestDataPath),
        cleanup: "EmptyParagraphs,UnusedRegions,UnusedFields,RemoveTitleRow,RemoveTitleRowInInnerTables",
        withRegions: true  //have to process twice if template contains enumerable data :( https://forum.aspose.cloud/t/mail-merge-word-document-from-xml-data-in-node-js-basics/8247/14
    });
    wordsApi.executeMailMergeOnline(regionMergeRequest)
    .then((regionMergeRequestResult) => {
        console.log("region merge complete");
        const convertRequest = new ConvertDocumentRequest({
            document: Readable.from(regionMergeRequestResult.body),
            format: "pdf"
        });
        wordsApi.convertDocument(convertRequest)
        .then((convertRequestResult) => {
            console.log("convert complete");
            fs.writeFile(outputPath, convertRequestResult.body, function (err) {
                if (err) return console.log(err);
                console.log('file saved');
            });
        })
        .catch((err) => {
            console.log(err);
        });
    }) 
    .catch((err) => {
        console.log(err);
    });
})
.catch((err) => {
    console.log(err);
});

@danobri,

Thanks for your feedback. However, while calling merge API twice with withRegion false and true, I noticed that addressLine2 and addressLine3 are removed in the output document. We will appreciate it if you please share your expected output document to understand the issue exactly.

coverageChange.pdf (100.3 KB)

I am unable to view the demoif zip can you please reshare

@omkarfusion

I am able to view the above attached demoIf.zip file. However, I have share it again.
demoIf.zip (11.1 KB)