SomeKittens
SomeKittens

Reputation: 39522

Render a non-specific amount of results with express/ejs

I'm trying to create a basic blog platform to help me get my feet wet with node. I'm using Express as a framework and ejs as my rendering engine. On my homepage, I'd like to display the last ten blogs. So far, I have:

"use strict";
var mongo = require("mongodb")
    , server = new mongo.Server("localhost", mongo.Connection.DEFAULT_PORT, {auto_reconnect: true, safe:true})
    , mdb = new mongo.Db("blog", server)
    , querystring = require("querystring")
    , express = require('express')
    , app = express();

app.configure(function() {
    app.set('view engine', 'ejs');
});

module.exports = {
    home: function home(req, res) {
        var blogs;
        //Load blogs from db
        mdb.open(function(err, db) {
            db.collection("blogs", function(err, collection) {
                var stream = collection.find({}, {"limit": 10, "sort": {"created": -1}}).stream();
                stream.on("data", function(item) {
                    app.render('blogItem', {title: item.title, content: item.content}, function(err, html) {
                        if(err) { console.error(err);   return; }
                        blogs += html;
                    });
                });
                //Render the finished page
                stream.on("end", function() {
                    res.render('home', {title: "AwesomeBlog", content: blogs});
                    db.close();
                });
            });
        });
    }
};

ejs files:

home.ejs

<!DOCTYPE html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %>!</h1>
<%= content %>
<a href="/admin">Admin section</a>
</body>

blogItem.ejs

<h4><%= title %></h4>
<p><%= content %></p>

While this technically "works", the rendered HTML per-blog is interpreted as plain text, resulting in

AwesomeBlog!

<h4>Hi</h4> <p>test 123</p> <h4>Awesome title</h4> <p>Awesome text</p> <h4>FIRST</h4> <p>POST!</p> Admin section

How can I fix this in this case?

What's the best practice for what I'm trying to do?

Upvotes: 0

Views: 611

Answers (1)

rdrey
rdrey

Reputation: 9529

That's a safety feature built-into EJS. It stops your users from embedding html that contains javascript exploits (XSS) in your pages. (They can still submit unsafe strings in form requests, etc, but your template escapes it to prevent browser exploits.)

To turn it off (for HTML content you can trust):

Escapes html by default with <%= code %>
Unescaped buffering with <%- code %>

Simply switch the tags in your template like this:

<h4><%= title %></h4>
<p><%- content %></p>

Upvotes: 2

Related Questions