EJS Example
This page documents the EJS view engine example included in the Express repository. It demonstrates how to configure Express to use EJS (Embedded JavaScript) as the template engine, how to render dynamic data, and how to compose pages using template inclusion patterns.
Overview
The EJS example shows a complete Express application that renders an HTML page listing users with their names and email addresses. The application uses EJS templates with a .html extension, includes partial templates for headers and footers, and serves static assets from a public directory.
File Structure
The example consists of the following files:
| File | Purpose |
|---|---|
examples/ejs/index.js | Application entry point and Express configuration |
examples/ejs/views/users.html | Main template that renders the user list |
examples/ejs/views/header.html | Reusable header partial with dynamic title |
examples/ejs/views/footer.html | Reusable footer partial |
examples/ejs/public/stylesheets/style.css | CSS stylesheet for the page |
Configuration and Setup
Registering EJS as the View Engine
The application registers EJS as the view engine by calling app.engine() with the .html extension and passing EJS's __express method examples/ejs/index.js:17-17:
app.engine('.html', require('ejs').__express);This call tells Express that any file with a .html extension should be processed by the EJS engine. The __express method is a standard function that template engines expose to integrate with Express's view system.
Setting the Views Directory
The views directory is set to the views folder relative to the application file examples/ejs/index.js:20-20:
app.set('views', path.join(__dirname, 'views'));Configuring the Default View Engine
To avoid specifying the file extension in every res.render() call, the application sets the default view engine examples/ejs/index.js:26-26:
app.set('view engine', 'html');This allows res.render('users') instead of res.render('users.html').
Serving Static Files
Static assets from the public directory are served using Express's built-in static middleware examples/ejs/index.js:23-23:
app.use(express.static(path.join(__dirname, 'public')));Route and Dynamic Data
The application defines a single route for the root path (/) that renders the users template with dynamic data examples/ejs/index.js:32-37:
app.get('/', function(req, res){
res.render('users', {
users: users,
title: "EJS example",
header: "Some users"
});
});The data passed to the template includes:
users: An array of user objects, each withnameandemailpropertiestitle: A string used in the HTML title tagheader: A string used as the page heading
The user data is defined as a placeholder array examples/ejs/index.js:29-31:
var users = [
{ name: 'tobi', email: 'tobi@learnboost.com' },
{ name: 'loki', email: 'loki@learnboost.com' },
{ name: 'jane', email: 'jane@learnboost.com' }
];Template Structure and Includes
Main Template (users.html)
The users.html template demonstrates template inclusion by embedding both the header and footer partials. It iterates over the users array to display each user's name and email. The template structure follows this pattern:
<%- include('header') %>
<!-- User list content -->
<%- include('footer') %>The <%- syntax in EJS outputs unescaped HTML, which is necessary for the include directive to render the included template content correctly.
Header Partial (header.html)
The header template receives the title variable from the parent template and uses it in the HTML <title> tag. It also links to the stylesheet served from the public directory.
Footer Partial (footer.html)
The footer template closes the HTML structure by providing the closing </body> and </html> tags.
Comparison with Other Examples
The EJS example differs from other Express examples in several ways:
| Aspect | EJS Example | Other Examples |
|---|---|---|
| Template Engine | EJS with .html extension | Jade/Pug, Handlebars, or others |
| Template Includes | Uses include directive | Varies by engine (partials, blocks) |
| Layout Pattern | Manual includes (header/footer) | Some engines support layout inheritance |
| File Extension | .html (remapped from .ejs) | Engine-specific extensions |
Unlike the MVC Example which organizes code into models, views, and controllers, this example keeps all logic in a single file. The Route Separation Example demonstrates a different organizational pattern where routes are defined in separate modules.
Running the Example
The application starts an HTTP server on port 3000 when executed directly examples/ejs/index.js:40-42:
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}The module.parent check ensures the server only starts when the file is run directly, not when required as a module by another file (such as a test suite).
Key Takeaways
- EJS is configured as the view engine by calling
app.engine('.html', require('ejs').__express)and setting the default view engine to'html' - Template includes are performed using the
<%- include('partial') %>syntax within EJS templates - Dynamic data is passed to templates as the second argument to
res.render(), which makes the data available as variables in the template - The views directory structure separates reusable partials (header, footer) from the main template
- Static files are served from a
publicdirectory usingexpress.static()