Express Template Variables
Introduction
Template variables are one of the most powerful features of Express templating engines. They allow you to create dynamic web pages by injecting data from your server into your HTML templates. Instead of creating static web pages, you can personalize content, display database results, and create interactive experiences for users.
In this tutorial, we'll explore how to work with template variables in Express.js using the EJS templating engine, one of the most popular choices for Express applications.
What Are Template Variables?
Template variables act as placeholders in your template files that get replaced with actual data when the template is rendered. They bridge the gap between your Express server and your front-end views, allowing you to pass information dynamically.
Think of them like filling in the blanks in a sentence:
- Static: "Hello, user!"
- Dynamic: "Hello,
{userName}
!" where{userName}
is a template variable that gets replaced with the actual user's name.
Setting Up Express with EJS
Before we dive into template variables, let's make sure we have our environment set up correctly:
const express = require('express');
const app = express();
const port = 3000;
// Set EJS as the templating engine
app.set('view engine', 'ejs');
// Specify the directory where templates are located
app.set('views', './views');
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
Make sure to install the necessary packages:
npm install express ejs
Basic Template Variables
Let's start with a simple example. First, create an EJS template file hello.ejs
in your views
folder:
<!DOCTYPE html>
<html>
<head>
<title>Hello Page</title>
</head>
<body>
<h1>Hello, <%= name %>!</h1>
<p>Welcome to our website.</p>
</body>
</html>
Now, let's create a route that renders this template with a variable:
app.get('/hello', (req, res) => {
res.render('hello', { name: 'John' });
});
When you visit /hello
in your browser, you'll see:
Hello, John!
Welcome to our website.
The <%= name %>
in the template is replaced with "John", which we passed in the object { name: 'John' }
.
How Template Variables Work
When you use the res.render()
method in Express, you pass two arguments:
- The name of the template to render
- An object containing all the variables you want to pass to the template
res.render('templateName', {
variable1: value1,
variable2: value2
});
Inside your template, you can access these variables using the EJS syntax <%= variableName %>
.
Different Ways to Use Template Variables
1. Simple Value Output
To simply output a variable's value, use <%= %>
:
<p>User: <%= username %></p>
2. Escaped Output
By default, <%= %>
escapes HTML. This means if your variable contains HTML tags, they'll be displayed as text, not rendered as HTML:
<%= "<h2>This will show as text, not a heading</h2>" %>
3. Unescaped Output
If you want to render HTML contained in a variable, use <%- %>
:
<%- "<h2>This will render as an actual heading</h2>" %>
Warning: Only use <%- %>
with trusted data, as it can introduce security vulnerabilities if used with user-provided content.
4. JavaScript in Templates
You can include JavaScript logic using <% %>
:
<% if (user.isLoggedIn) { %>
<h2>Welcome back, <%= user.name %>!</h2>
<% } else { %>
<h2>Hello, guest!</h2>
<% } %>
More Complex Examples
Passing Multiple Variables
app.get('/profile', (req, res) => {
res.render('profile', {
username: 'coder123',
fullName: 'Jane Smith',
joinDate: new Date('2020-01-15'),
isAdmin: true
});
});
In your profile.ejs
template:
<h1>Profile: <%= username %></h1>
<p>Name: <%= fullName %></p>
<p>Joined: <%= joinDate.toLocaleDateString() %></p>
<% if (isAdmin) { %>
<div class="admin-badge">Administrator</div>
<% } %>
Working with Arrays
app.get('/todos', (req, res) => {
const todoList = [
{ id: 1, task: 'Buy groceries', completed: false },
{ id: 2, task: 'Finish homework', completed: true },
{ id: 3, task: 'Call mom', completed: false }
];
res.render('todos', { todos: todoList });
});
In your todos.ejs
template:
<h1>Todo List</h1>
<ul>
<% todos.forEach(todo => { %>
<li class="<%= todo.completed ? 'completed' : '' %>">
<%= todo.task %>
<% if (todo.completed) { %>
<span class="badge">✓</span>
<% } %>
</li>
<% }); %>
</ul>
Using Functions in Templates
You can also pass functions to your templates:
app.get('/helpers', (req, res) => {
res.render('helpers', {
formatCurrency: (amount) => {
return '$' + amount.toFixed(2);
},
capitalizeFirstLetter: (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
}
});
});
In your helpers.ejs
template:
<p>Price: <%= formatCurrency(29.99) %></p>
<p>Name: <%= capitalizeFirstLetter('john') %></p>
Output:
Price: $29.99
Name: John
Real-World Application: Building a Blog
Let's create a more comprehensive example. Imagine we're building a simple blog:
// Server-side code
app.get('/blog', (req, res) => {
// This data might come from a database in a real app
const blogPosts = [
{
id: 1,
title: 'Getting Started with Express',
author: 'Sarah Johnson',
date: new Date('2023-01-15'),
content: 'Express.js is a minimal and flexible Node.js web application framework...',
comments: 5
},
{
id: 2,
title: 'Template Engines in Express',
author: 'Mike Brown',
date: new Date('2023-02-28'),
content: 'Template engines enable you to use static template files in your application...',
comments: 3
}
];
const user = {
name: 'Guest User',
isAdmin: false,
preferences: {
darkMode: true
}
};
res.render('blog', {
posts: blogPosts,
user: user,
formatDate: (date) => {
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
}
});
});
In your blog.ejs
template:
<!DOCTYPE html>
<html>
<head>
<title>My Blog</title>
<style>
body {
/* Apply dark mode based on user preference */
background-color: <%= user.preferences.darkMode ? '#222' : '#fff' %>;
color: <%= user.preferences.darkMode ? '#eee' : '#333' %>;
}
/* More styles... */
</style>
</head>
<body>
<header>
<h1>My Tech Blog</h1>
<p>Welcome, <%= user.name %></p>
<% if (user.isAdmin) { %>
<a href="/admin">Admin Dashboard</a>
<% } %>
</header>
<main>
<% posts.forEach(post => { %>
<article>
<h2><%= post.title %></h2>
<div class="meta">
By <%= post.author %> on <%= formatDate(post.date) %>
</div>
<div class="content">
<%= post.content %>
</div>
<footer>
<a href="/post/<%= post.id %>#comments"><%= post.comments %> Comments</a>
</footer>
</article>
<% }); %>
</main>
</body>
</html>
This example demonstrates several important concepts:
- Passing complex nested objects (
user.preferences.darkMode
) - Using helper functions (
formatDate
) - Conditional rendering based on user properties
- Looping through arrays
- Dynamic styles based on variables
- Creating dynamic links with variables
Best Practices
-
Keep Templates Clean: Avoid putting too much logic in your templates. If you find yourself writing complex JavaScript in your templates, consider moving that logic to your Express routes or to helper functions.
-
Create Helper Functions: For complex formatting or calculations, create helper functions and pass them to your templates.
-
Use Defaults for Optional Variables: If a variable might be undefined, provide a default value:
html<p>Author: <%= author || 'Anonymous' %></p>
-
Always Escape User Data: When displaying user-provided data, always use
<%= %>
(not<%- %>
) to prevent XSS attacks. -
Structure Your Data: Pass well-structured data objects to templates rather than many individual variables.
Summary
Template variables in Express allow you to create dynamic web pages by injecting data from your server into your templates. With EJS, you can:
- Output simple values with
<%= %>
- Include unescaped HTML with
<%- %>
- Use conditional logic and loops with
<% %>
- Pass complex data structures like objects and arrays
- Include helper functions for formatting and other operations
By mastering template variables, you can create rich, interactive web applications that respond to user preferences, display database content, and provide personalized experiences.
Additional Resources
- EJS Documentation
- Express Guide to Template Engines
- Security Best Practices for Express Applications
Exercises
-
Create a "User Profile" page that displays different information based on whether a user is logged in or not.
-
Build a "Product Listing" page that shows different products and highlights items that are on sale.
-
Create a "Weather Dashboard" that formats temperatures differently based on whether they're hot or cold.
-
Implement a "Blog Post" page that shows or hides the comments section based on whether there are any comments.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)