3

I am initializing nunjucks inside my express app.js file, and registering a custom addfilter function in the same file just fine:

  // get needed packages
const nunjucks = require('nunjucks');

  // config view engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');

  // set variable
const env = nunjucks.configure('views', {
  autoescape: true,
  express: app
});

  // register custom helper
env.addFilter('shorten', function(str, count) {
  return str.slice(0, count || 5);
});

However, I have a stack more of these addfilter functions that I would like to add, but I don't want put them in my app.js file. Specifically, I would like to put them here:

node-project/views/helpers/nunjucks_helpers.js

What would be the node express way to configure this package to register custom filters like this one in said other file?

johnny_void
  • 53
  • 1
  • 7

2 Answers2

3

Minimum code change

Create a function in nunjucks_helpers.js that takes env as a parameter and export it:

// helpers/nunjucks_helpers.js
function addNunjucksFilters(nunjucksEnvironment) {
  nunjucksEnvironment.addFilter(...);
  // Add all your other calls to addFilter here
}

module.exports = addNunjucksFilters;

Then import it into app.js and call it:

// app.js
var addNunjucksFilters = require('./helpers/nunjucks_helpers.js'); // Path might be different - depends on where you put app.js
// ... your existing code
addNunjucksFilters(env);

More info about including functions from other files in this Q and A.

Separation of concerns

To get better separation of concerns, you can move everything nunjucks-related out of app.js:

// helpers/nunjucks-helper.js:
const nunjucks = require('nunjucks');

function setUpNunjucks(expressApp) {
  const env = nunjucks.configure('views', {
    autoescape: true,
    express: app
  });

  // register custom helper
  env.addFilter('shorten', function(str, count) {
    return str.slice(0, count || 5);
  });
  // ... your other filters here
}

Which leaves your app.js looking a lot more clean:

// app.js
const setUpNunjucks = require('./helpers/nunjucks_helpers.js');

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
setUpNunjucks(app);
stone
  • 8,422
  • 5
  • 54
  • 66
  • 1
    It works perfectly! I am amazed at this feature, and see finally how powerful requiring files while exporting modules can be for organization. I had reviewed the thread you left previously, but was I not able to apply it to my own problem without such an explicit demo. Thank you! – johnny_void Jan 19 '18 at 08:43
  • 1
    Thanks, I really appreciate responses that show multiple ways to address a problem - they make us all better engineers. – Eric Kigathi Dec 20 '18 at 01:15
  • 1
    This deserves more upvotes. Works great in Express 4 – klewis Feb 22 '21 at 22:22
2

My original code had a bug in it which made it into the Separation of Concerns section of Stone's answer. It is a great tip, and everything works fine if you change that block to set the nunjucks env variable properly:

// helpers/nunjucks-helper.js:
const nunjucks = require('nunjucks');

function setUpNunjucks(expressApp) {
  // set variable
  const env = nunjucks.configure('views', {
    autoescape: true,
    express: expressApp
  });

  // register custom helper
  env.addFilter('shorten', function(str, count) {
    return str.slice(0, count || 5);
  });
  // ... your other filters here
}
CodeLoop
  • 35
  • 3
johnny_void
  • 53
  • 1
  • 7