Tutorial: Embedded JavaScript templates (EJS) and Node.js

Post to Twitter

There are several ways to create web applications with Node.js. One popular way is to use Jade. Today, I’ll show you how to use EJS (Embedded JavaScript templates) with Node.js to create a simple web application. If you’ve used PHP or classic ASP then this will probably look very familiar.

Note: I’ll assume from here that you already have Node.js installed.

Some of this code is borrowed (and modified) from the example provided here.

We will start our project by creating a new folder called EJSDemo. Inside of that folder create a file called app.js. Add the following code to app.js:

var express = require('express')
    , app = module.exports = express();

// Using the .html extension instead of
// having to name the views as *.ejs
app.engine('.html', require('ejs').__express);

// Set the folder where the pages are kept
app.set('views', __dirname + '/views');

// This avoids having to provide the 
// extension to res.render()
app.set('view engine', 'html');

// Serve the index page
app.get('/', function(req, res){
  res.render('index', {
    // PLACEHOLDER
    pageTitle: 'EJS Demo'
  });
});

if (!module.parent) {
  app.listen(8080);
  console.log('EJS Demo server started on port 8080');
}

The comments in the code should explain what is going on.

As you can probably guess by now you need to have Express and EJS installed. You can use NPM to do this from the command line inside of the EJSDemo folder:

$ npm install express
$ npm install ejs

Let’s move onto the index view now. Inside of the EJSDemo folder create a new folder called views. Inside of the views folder add three files called index.html, header.html and footer.html

Edit the header.html file first and add the following HTML in it:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title><%= pageTitle %></title>
</head>
<body>

The header.html file contains HTML markup that is common to any of the files we might add to this project. This also means our footer.html will have some default HTML that is common to all the files in this project so let’s go ahead and add that HTML to footer.html file:

</body>
</html>

Above we are simply closing off the HTML tags we opened in the header.html file.

Let’s edit the index.html file now as follows:

<% include header.html %>
PLACEHOLDER
<% include footer.html %>

I’ve included our two templates for the footer and header. Although this is pretty minimal let’s go ahead and run this.

$ node app.js

Hit this address with a web browser:
http://localhost:8080/

Nothing fancy, but you will notice the page’s title was passed through via EJS. Now we can make this a bit more complex. Stop the Node.js server and go ahead and modify the app.js file to look like the following:

var express = require('express')
    , app = module.exports = express();

// Using the .html extension instead of
// having to name the views as *.ejs
app.engine('.html', require('ejs').__express);

// Set the folder where the pages are kept
app.set('views', __dirname + '/views');

// This avoids having to provide the 
// extension to res.render()
app.set('view engine', 'html');

var messages = [
  { name: 'Nathan Explosion', message: 'Dethklok rules' },
  { name: 'William Murderface', message: 'Bass is the heart of the band' },
  { name: 'Dr. Rockso', message: 'Where is my friend Toki?' }
];

// Serve the index page
app.get('/', function(req, res){
  res.render('index', {
    pageTitle: 'EJS Demo',
    messages: messages
  });
});

if (!module.parent) {
  app.listen(8080);
  console.log('EJS Demo server started on port 8080');
}

Modify the index.html page to print out the messages we added:

<% include header.html %>

<strong>Dethklok Band Messages</strong>
<ul>
  <% messages.forEach(function(msgObj){ %>
    <li><%= msgObj.name %> says: <%= msgObj.message %></li>
  <% }) %>
</ul>

<% include footer.html %>

The above code takes the messages object that is passed and then iterates through it using the forEach call. Each time we find a message we print it out.

Save the files and run the app.js file again hitting the same URL as before. You should see output similar to this:

There is also a filter feature in EJS so if you wanted to change all the name values to uppercase you could do this in the index.html file:

<% include header.html %>

<strong>Dethklok Messages</strong>
<ul>
  <% messages.forEach(function(msgObj){ %>
    <li><%=: msgObj.name | upcase %> says: <%= msgObj.message %></li>
  <% }) %>
</ul>

<% include footer.html %>

The trick here is this piece of code:

<%=: msgObj.name | upcase %>

Please note the colon used for filters

<%=: %>

Results in the browser:

There are plenty of filters to try out than just uppercase and you can find a list on the EJS homepage.

Post to Twitter

This entry was posted in JavaScript, Node.js, Open Source. Bookmark the permalink.

4 Responses to Tutorial: Embedded JavaScript templates (EJS) and Node.js

  1. Pingback: Get the string and array from the Express.js in html file | Tony's programming note

  2. sarath says:

    code works well !!!!!! good tut on ejs!!!

  3. Thor says:

    Thanks for taking the time to put this tutorial together. The examples worked perfectly and your explanations were quick and clear. Nicely done!

  4. Andrés says:

    Great! but I have a question: how do you print messages without forEach?

Comments are closed.