{"action":"closed","issue":{"url":"https://api.github.com/repos/loulin/notebook/issues/1","repository_url":"https://api.github.com/repos/loulin/notebook","labels_url":"https://api.github.com/repos/loulin/notebook/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/loulin/notebook/issues/1/comments","events_url":"https://api.github.com/repos/loulin/notebook/issues/1/events","html_url":"https://github.com/loulin/notebook/issues/1","id":176526193,"number":1,"title":"NUNJUCKS: INJECT EXPRESS REQUEST TO TEMPLATES","user":{"login":"loulin","id":1905704,"avatar_url":"https://avatars.githubusercontent.com/u/1905704?v=3","gravatar_id":"","url":"https://api.github.com/users/loulin","html_url":"https://github.com/loulin","followers_url":"https://api.github.com/users/loulin/followers","following_url":"https://api.github.com/users/loulin/following{/other_user}","gists_url":"https://api.github.com/users/loulin/gists{/gist_id}","starred_url":"https://api.github.com/users/loulin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loulin/subscriptions","organizations_url":"https://api.github.com/users/loulin/orgs","repos_url":"https://api.github.com/users/loulin/repos","events_url":"https://api.github.com/users/loulin/events{/privacy}","received_events_url":"https://api.github.com/users/loulin/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/loulin/notebook/labels/2016","name":"2016","color":"b60205"},{"url":"https://api.github.com/repos/loulin/notebook/labels/Node.js","name":"Node.js","color":"c5def5"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-09-13T01:32:32Z","updated_at":"2016-09-13T01:33:14Z","closed_at":"2016-09-13T01:33:14Z","body":"http://blog.eexit.net/nunjucks-inject-express-request/\r\nBy Joris Berthelot\r\nPublished March 23rd 2016\r\n\r\nOn my free time, I recently started to think about the next version of my photography portfolio which starts to be old and especially is not designed to be effectively browsable on tablets. \r\nAnd, there are also other things I'd like to fix...\r\n\r\nAnyway, as I recently got some basic skills in NodeJS, I challenged myself to rewrite my dear portfolio with this technology. I looked for an interesting templating engine not too far from Twig which I like a lot then I chose to go with Nunjucks, which is very similar and seems not to be dead.\r\n\r\nIn my current portfolio, I use Silex which is built on the top of a DIC. The Twig Service Provider has an excellent interesting idea of injecting the whole Silex application in a Twig global variable.\r\n\r\nThis was very convenient when, from the template, you need to access to the HTTP Request params for example. Or if you need to access to a service, etc. \r\nI personally rather choose to inject the services/data I need than exposing all of them.\r\n\r\nNunjucks also has the ability to add global variables, services, etc. but when it came to reach to the Express request, I started to rack my brains. \r\nI was hoping Nunjucks could do that but as the Express integration is more sort of a helper than a real extension of the template engine, the answer was no.\r\n\r\nI tried to play with it by setting up examples but it did not work and after a dull search on the Internet, I found what I wanted. Even I wish it was more elegant.\r\n\r\nI wrote this article to share a more elegant way (well, I believe it is...) to inject Express content as Nunjucks global variables.\r\n\r\nProject directory tree\r\n```\r\n.\r\n├── README.md\r\n├── app\r\n│   ├── config.js\r\n│   ├── index.js\r\n│   ├── middleware\r\n│   │   ├── error-handler.js\r\n│   │   └── inject-globals.js\r\n│   ├── route\r\n│   │   └── index.js\r\n│   ├── service\r\n│   │   ├── TemplateEngine.js\r\n│   │   └── index.js\r\n│   └── view\r\n│       ├── front\r\n│       ├── macro.njk\r\n│       └── skeleton.njk\r\n├── env\r\n├── package.json\r\n├── public\r\n└── server.js\r\n```\r\nI have the server and the application bootstrap in server.js, that's what npm start will run. My application kernel is in app/index.js while its configuration lays in app/config.js.\r\n\r\nThe rest is pretty much standard, I guess it evolves from project to project. The organization of a NodeJS project is still something that might evolve over time :).\r\n\r\nNunjucks integration\r\n\r\nThe files that arouse interest are:\r\n```\r\napp/service/TemplateEngine.js\r\napp/middleware/inject-globals.js\r\napp/index.js\r\n```\r\nI chose to create a badly-named template engine service: TemplateEngine.js:\r\n```js\r\nvar nunjucks = require('nunjucks');  \r\nvar config = require(__dirname + '/../config').template;\r\n\r\nmodule.exports.init = function (app) {  \r\n    var env = nunjucks.configure(config.path, {\r\n        throwOnUndefined: config.strict,\r\n        autoescape: true,\r\n        watch: config.watch,\r\n        noCache: config.cache,\r\n        express: app\r\n    })\r\n    .addFilter('json', JSON.stringify);\r\n\r\n    // Sets Nunjucks as the Express template engine\r\n    app.set('engine', env);\r\n};\r\n```\r\nHere you configure your template engine and I believe it would be the best place to append a bunch of filters as well.\r\n\r\nInto the application kernel (app/index.js), I set up my services and routes:\r\n```js\r\nvar service = require(__dirname + '/service');\r\n\r\nmodule.exports = function (app) {  \r\n    app.use(require('body-parser').json());\r\n\r\n    // Registers template engine\r\n    service.TemplateEngine.init(app);\r\n\r\n    // Injects global variables into the template engine\r\n    app.use(require(__dirname + '/middleware/inject-globals'));\r\n\r\n    // Application routes\r\n    require(__dirname + '/route')(app);\r\n\r\n    // Application error handler\r\n    app.use(require(__dirname + '/middleware/error-handler'));\r\n};\r\n```\r\nHere I briefly configure my Express framework then I register the template engine. As I wrote earlier, I might re-work the interface/naming of the template engine service. \r\nAnyway, right after I declare a catch-all middleware in which I will append Nunjucks Express variables.\r\n\r\nHere's the content of app/middleware/inject-globals.js:\r\n```js\r\nmodule.exports = function (req, res, next) {  \r\n    var engine = res.app.get('engine');\r\n    var config = req.app.get('config');\r\n\r\n    engine.addGlobal('config', config);\r\n    engine.addGlobal('request', req);\r\n\r\n    next();\r\n};\r\n```\r\nAs simple as it looks like. I chose here to inject the incoming request and my application configuration.\r\n\r\nIn your template file, you can have access at your request bag, such as headers for example:\r\n\r\n`<code>{{ request.headers | json(null, 4) }}</code> ` \r\nPretty cool no?\r\n\r\nNow you know how to inject Express request or any other data you need into your template files without having to manually inject at each single rendering call.\r\n\r\nI believe there plenty things to improve in all aspects of what I've shown above but I'm no expert so if you have feedback, please share!\r\n\r\nThank you!\r\n\r\nJoris Berthelot"}}
{"actor":{"display_login":"loulin"}}