Node.js | EJS Template Engine
Installing EJS with npm
Previously, displaying HTML files required reading files asynchronously and replacing parts of HTML manually. A simpler approach is to use a template engine. Node.js can use many template engines, and one of the most common is EJS.
Install EJS with npm.
npm install ejs
npm is essential when using Node.js because most required libraries can be installed with npm install. EJS can also be obtained from GitHub.
https://github.com/visionmedia/ejs
Special Tags Available in Templates
EJS embeds information into HTML templates with special tags.
<%= value %>
Writes the value at that position. It is used to display variables prepared in the script. HTML tags are escaped.
<%- value %>
Also writes the value at that position, but HTML-related tags are not escaped.
<% script %>
Writes script that is executed during rendering. Unlike a browser <script> tag, this runs on the server side in Node.js, and the result is sent to the client.
Create hello.ejs in the same location as the Node.js script.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title><%=title %></title>
</head>
<body>
<header>
<h1 id="h1"><%=title %></h1>
</header>
<div role="main">
<p><%-content %></p>
</div>
</body>
</html>
The tags <%=title %> and <%-content %> output variables named title and content passed from the script.
Displaying a Template with EJS
To load the template file and display a web page, you need to read the file, render the template data, and write the generated data to the response.
var http = require('http');
var fs = require('fs');
var ejs = require('ejs');
var hello = fs.readFileSync('./hello.ejs', 'utf8');
var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');
function doRequest(req, res) {
var hello2 = ejs.render(hello, {
title:"Title",
content:"This is a template created for the sample.",
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(hello2);
res.end();
}
Load EJS with require('ejs'). Read the template with fs.readFileSync. Although this is synchronous, it is done before the server is created, so it is suitable for loading templates once into global variables.
Render the template with:
ejs.render(templateData, options);
The first argument is the template string, and the second argument is an associative array of variables passed to the template. Finally, set Content-Type to text/html and write the response.
Combining Template Parts
A template can also be combined with another template. For example, prepare a whole-page template and insert a content template into it.
Create content1.ejs.
<p>This is a template created for the example.</p>
<p>It reads and uses content prepared in another file.</p>
<p><%= message %></p>
Then render the inner template first and pass the result into the outer template.
var http = require('http');
var fs = require('fs');
var ejs = require('ejs');
var hello = fs.readFileSync('./hello.ejs', 'utf8');
var content1 = fs.readFileSync('./content1.ejs', 'utf8');
var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');
function doRequest(req, res) {
var hello2 = ejs.render(hello, {
title: "Title",
content: ejs.render(content1,{
message:"Text message"
})
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(hello2);
res.end();
}
The basic rule when combining templates is to render the inner template first, then pass the rendered result as an option to the outer render. If you insert an unrendered template and then render later, tags inside the inserted template may appear without being processed.
Repeatedly Outputting Array Data
EJS can execute JavaScript script with <% %> during server-side rendering. There are a few points to remember.
- Content written inside
<% %>is not displayed. To output a value, leave the script block and use<%= %>. - It is JavaScript, but browser-dependent features such as
alertanddocumentcannot be used. - Variables passed during rendering can be used inside
<% %>.
Modify content1.ejs as follows.
<p>This is a template created for the example.</p>
<p>Array data is returned and displayed as a list.</p>
<p><ol>
<% data.forEach(function(val){ %>
<li><%= val %></li>
<% }) %>
</ol></p>
Pass array data from the script.
var hello2 = ejs.render(hello, {
title: "Title",
content: ejs.render(content1, {
data: [
"This is the first data.",
"The next data.",
"The final data."
]
})
});
The output part uses <%= %>, while the loop processing uses <% %>.
<% data.forEach(function(val){ %>
<li><%= val %></li>
<% }) %>
If forEach is unfamiliar, you can write a normal for loop instead.
<% for (var i = 0;i < data.length;i++){ %>
<li><%= data[i] %></li>
<% } %>
When using <% %>, remember to separate processing and output clearly.