Fixing Swig’s Template Inheritance on Express for NodeJS
Today I was playing around with the Swig templating engine on Express for NodeJS, and I came to a problem:
Extending templates doesn’t work
I was using two template files:
index.html
{% extends 'layout.html' %}
{% block site_title %}{{title}}{% endblock %}
layout.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{% block site_title %}My App{% endblock %}</title>
</head>
<body>
<h1>{{title}}</h1>
</body>
</html>
My app.js code was:
var express = require('express')
, swig = require('swig')
, cons = require('consolidate')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, VIEWS_DIR = __dirname + '/views';
var app = express();
// assign the swig engine to .html files
app.engine('html', cons.swig);
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', VIEWS_DIR);
app.set('view engine', 'html');
app.set('view options', { layout: false });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
…and I run into this error:
Error: Circular extends found on line 3 of…
But, after a few hours investigating I got it! You only have to initialize the Swig engine like this:
swig.init({
root: VIEWS_DIR, //Note this directory is your Views directory
allowErrors: true // allows errors to be thrown and caught by express
});
So, finally, the code looks like this:
var express = require('express')
, swig = require('swig')
, cons = require('consolidate')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, VIEWS_DIR = __dirname + '/views';
var app = express();
swig.init({
root: VIEWS_DIR, //Note this directory is your Views directory
allowErrors: true // allows errors to be thrown and caught by express
});
// assign the swig engine to .html files
app.engine('html', cons.swig);
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', VIEWS_DIR);
app.set('view engine', 'html');
app.set('view options', { layout: false });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
Hope this help!
Happy coding!
Update: You can find it in the docs (https://github.com/paularmstrong/swig/blob/master/docs/express.md
https://github.com/paularmstrong/swig/blob/master/examples/express/server.js).
Thanks to @paularmstrong.
