Search code examples
node.jsexpressswig-template

Render document field as HTML


I'm creating my first sample code using NodeJS, Express, MongoDB and Swig. It's a small blog application and I'm trying to render the existing posts, however, the post body contains HTML tags and they are printed as text.

How can I render them as HTML?

Here is my view (main.html):

<p>
    <h3>{{title}}</h3>
    <h6><i>{{postedAt}}</i></h6>
</p>
<p>
    {{content}}
</p>

And here is the app.js:

var express = require('express');
var cons = require('consolidate');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;


app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

var mongoClient = new MongoClient(new Server('localhost', 27017, 
                                             { 'native_parser' : true }));

var db = mongoClient.db('blog');

// Base URL - Show posts
app.get('/', function (request, response) {
    var cursor = db.collection('posts').find().sort({'postedAt': 1});

    cursor.each(function (err, doc) {
        if (err) throw err;

        if (doc == null) {
            return db.close();
        }

        response.render('main', doc);
    });
});



app.get('*', function (request, response) {
    response.send('Page not found', 404);
});

mongoClient.open(function (err, client) {

    if (err) throw err;

    app.listen(8080);
    console.log('Express started listening on port 8080');
});

Solution

  • Swig HMTL-escapes all variables by default.

    If you’re sure the content in question is safe (i.e. the HTML doesn’t include malicious JavaScript), then you can turn off HMTL-escaping using the safe filter:

    <p>
        <h3>{{title}}</h3>
        <h6><i>{{postedAt}}</i></h6>
    </p>
    <p>
        {{content|safe}}
    </p>