Search code examples
javascriptfilternunjucks

Sharing nunjucks filters across node and browser


I am trying to find a way to get my filter works on both side.

Here is the code I have on node :

var env = nunjucks.configure(__dirname + '/../templates', {
    express: app
});

env.addFilter('date', function(str){
    return 'ok';
});

And on browser side :

var env = new nunjucks.Environment();
env.addFilter('date', function(str){
    return 'ok';
});

I would like to have my filter in a place where it will be available in these two different environments but I don't find a solution to do so.

On client side I am using nunjucks-slim version. My templates are precompiled using gulp.

Thanks for your help !


Solution

  • You could put your filters in a separate file/module, where you pass env in as an argument.

    eg.

    /**
    * @param env The nunjucks environment
    */
    function(env){
        env.addFilter('fancy', function(input){
            return 'fancy ' + input
        });
    
        env.addFilter(...);
    
        return env;
    }
    

    You could then use a UMD wrapper (https://github.com/umdjs/umd) to make it compatible with both browser and server. The finished wrapper might look something like this:

    // custom_filters.js
    (function (root, factory) {
        if (typeof define === 'function' && define.amd) {
            // AMD. Register as an anonymous module.
            define([], factory);
        } else if (typeof exports === 'object') {
            // Node. Does not work with strict CommonJS, but
            // only CommonJS-like environments that support module.exports,
            // like Node.
            module.exports = factory();
        } else {
            // Browser globals (root is window)
            root.custom_filters = factory();
        }
    }(this, function () {
    
        // Return a value to define the module export.
        return function(env){
            env.addFilter('fancy', function(input){
                return 'fancy ' + input
            });
    
            return env;
        };
    }));
    

    Then use it like this:

    Node:

    var env = nunjucks.configure(__dirname + '/../templates', {
        express: app
    });
    require('./path/to/custom_filters')(env);
    

    Browser (Globals):

    var env = new nunjucks.Environment();
    window.custom_filters(env);
    

    Browser (AMD):

    define(
        ['nunjucks', 'path/to/custom_filters'],
        function(nunjucks, custom_filters){
            var env = new nunjucks.Environment();
            return custom_filters(env);
        }
    );