Swig Template CLI + Browser Usage + Custom filters

I'm trying to use Swig template for Nodejs in the browser.

The requirement:

I need to use custom filters in my precompiled templates with Swig CLI.

The issue:

The result of my compilation doesn't have the custom filters functions and I get an error (Step 5 below).

The steps I've made

1- Compile the template

Template:

<span>{{ item.sampleProperty|customFilterTwo }}</span>

Filters file [filters.js]:

module.exports = {
    customFilterTwo: function(sampleProperty) {
        return sampleProperty + " rocks!";
    }
}

Command swig CLI:

swig compile ./views/macros/item.html > ./views/templates/item.js --filters=./views/filters/filters.js

2- Result of compilation

var tpl = function (_swig,_ctx,_filters,_utils,_fn) {
  var _ext = _swig.extensions,
    _output = "";
_output += "<span>";
_output += _filters["e"](_filters["customFilterTwo"]((((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? _ctx.item.sampleProperty : "") : ((typeof item !== "undefined" && item !== null && item.sampleProperty !== undefined && item.sampleProperty !== null) ? item.sampleProperty : "")) !== null ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? _ctx.item.sampleProperty : "") : ((typeof item !== "undefined" && item !== null && item.sampleProperty !== undefined && item.sampleProperty !== null) ? item.sampleProperty : "")) : "" )));
_output += "</span>";

  return _output;

};

3- Load Swig library and the js of the compiled template in the browser

4- Use the compiled js through the generated function tpl()

var html = swig.run(tpl, { 'item': item });

5- Get the error when running

TypeError: _filters.customFilterTwo is not a function

I know I need to tell Swig about the filters, buy I want a fully independent compiled template. I don't want to tell again Swig about these filters.

My Solution:

I've been researching about how to do that and I have made some modifications in Swig library to approach this.

In bin/swig.js replace the line 129 with:

// Compile any custom filters
var customFilters = "";
    if (argv.filters) {
      utils.each(require(path.resolve(argv.filters)), function (filter, name) {
        customFilters += "_filters['" + name + "'] = " + filter + ";\n";
      });
    }

    var r = swig.precompile(str, { filename: file, locals: ctx, customFilters: customFilters }).tpl.toString().replace('anonymous', '');

In lib/swig.js in line 486 add:

options.customFilters + '\n' +

And the result of the compiled js now have the provided filters:

var tpl = function (_swig,_ctx,_filters,_utils,_fn) {
    var _ext = _swig.extensions,
    _output = "";
    _filters["customFilterTwo"] = function(sampleProperty) {
        return sampleProperty + " rocks!";
    };
    _output += "<span>";
    _output += _filters["e"](_filters["customFilterTwo"]((((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? _ctx.item.sampleProperty : "") : ((typeof item !== "undefined" && item !== null && item.sampleProperty !== undefined && item.sampleProperty !== null) ? item.sampleProperty : "")) !== null ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? ((typeof _ctx.item !== "undefined" && _ctx.item !== null && _ctx.item.sampleProperty !== undefined && _ctx.item.sampleProperty !== null) ? _ctx.item.sampleProperty : "") : ((typeof item !== "undefined" && item !== null && item.sampleProperty !== undefined && item.sampleProperty !== null) ? item.sampleProperty : "")) : "" )));
    _output += "</span>";

      return _output;

    };

And now the script is fully independent and doesn't need add the filters to swig.


I wish I have explained well enough. Sorry for my bad English.

I'm killing flies with cannon?? There is another easier way to approach this?

Thanks in advance

The instance of swig in your step 4 needs to also know about your filters.

swig.setFilter('customFilterTwo', customFilterTwoMethod);
var html = swig.run(tpl, { 'item', item })