Angular parser

The angular-parser makes creating complex templates easier. You can for example now use :

{user.name}

To access the nested name property in the following data :

{
    user: {
        name: 'John'
    }
}

You can also use +, -, *, /, >, < operators.

You also get access to filters :

It is possible to write the template {user.name | upper}, and have the resulting string be uppercased.

expressions.filters.upper = function(input) {
    // This condition should be used to make sure that if your input is undefined, your output will be undefined as well and will not throw an error
    if(!input) return input;
    return input.toUpperCase();
}

Here’s a code sample for how to use the angularParser :

// Please make sure to use angular-expressions 1.0.1 or later
// More detail at https://github.com/open-xml-templating/docxtemplater/issues/488
var expressions = require('angular-expressions');
var merge = require("lodash/merge");
// define your filter functions here, for example, to be able to write {clientname | lower}
expressions.filters.lower = function(input) {
    // This condition should be used to make sure that if your input is undefined, your output will be undefined as well and will not throw an error
    if(!input) return input;
    return input.toLowerCase();
}
function angularParser(tag) {
    if (tag === '.') {
        return {
            get: function(s){ return s;}
        };
    }
    const expr = expressions.compile(
        tag.replace(/(’|‘)/g, "'").replace(/(“|”)/g, '"')
    );
    return {
        get: function(scope, context) {
            let obj = {};
            const scopeList = context.scopeList;
            const num = context.num;
            for (let i = 0, len = num + 1; i < len; i++) {
                obj = merge(obj, scopeList[i]);
            }
            return expr(scope, obj);
        }
    };
}
new Docxtemplater().loadZip(zip).setOptions({parser:angularParser})

Note

The require() will not work in a browser, you have to use a module bundler like webpack or browserify. Alternatively, you can download an outdated version at https://raw.githubusercontent.com/open-xml-templating/docxtemplater/6c8c76210d555fd0f6b3dbc927522a3805f17469/vendor/angular-parse-browser.js

See for a complete reference of all possibilities of angularjs parsing: http://teropa.info/blog/2014/03/23/angularjs-expressions-cheatsheet.html

Conditions

With the angularParser option set, you can also use conditions :

{#users.length>1}
There are multiple users
{/}

{#userName == "John"}
Hello John, welcome back
{/}

The first conditional will render the section only if there are 2 users or more.

The second conditional will render the section only if the userName is the string “John”.

It also handles the boolean operators AND &&, OR ||, +, -, the ternary operator a ? b : c, operator precendence with parenthesis (a && b) || c, and many other javascript features.

For example, it is possible to write the following template :

{#generalCondition}
{#cond1 || cond2}
Paragraph 1
{/}
{#cond2 && cond3}
Paragraph 2
{/}
{#cond4 ? users : usersWithAdminRights}
Paragraph 3
{/}
There are {users.length} users.
{/generalCondition}