While studying and exploring Node.js and Express, I came across Template Engines. While it's possible to create static websites from a server, there are a lot of limitations, including code duplication and a lack of flexibility, especially when it comes to reading data from a database. Thanks to Express.js, it provides us with a way to create dynamic HTML pages from our server-side applications through a template engine.
Template engines are essentially software tools or libraries that enable the generation of dynamic content by combining predefined templates with data. It's similar to creating a template syntax and passing variables into it.
A template engine provides a means to define templates, typically written in a markup language or a specialized template language. These templates include placeholders or tags that are replaced with actual data during runtime. The template engine takes the template and the data, processes them, and generates the final output, which is often in HTML, XML, or other text-based formats.
Template engines offer several benefits
Separation of Concerns: Template engines allow developers to separate the presentation layer from the application logic. Templates focus on the visual representation, while the underlying code handles data manipulation.
Reusability: Templates can be reused across multiple pages or components, which promotes code modularization and reduces duplication.
Maintainability: By separating the presentation layer from the business logic, it becomes easier to maintain and update the application. Changes to the design or layout can be made in templates without affecting the underlying code.
Productivity: Template engines provide a higher level of abstraction, making it easier to work with dynamic content and handle repetitive tasks. They often offer features like conditional statements, loops, filters, and partials, which simplify the template creation process.
Collaboration: Template engines facilitate collaboration between designers and developers. Designers can focus on creating visually appealing templates, while developers can integrate them with the application logic.
Integrating Express template engines
Integrating a template engine into your Express application only takes a few lines of code. Just after assigning the Express function (before creating your routes), add the following app settings:
views
, the directory where the template files are located (e.g.,app.set('views', './views')
). This defaults to theviews
directory in the application's root directoryNow setting your template engine ie.
view engine
. For example, to use the Pug template engine:app.set('view engine', 'pug')
.
Some popular template engines that work with Express
Pug (formerly Jade):
Pug is a high-performance template engine for Node.js and JavaScript that focuses on simplicity and readability. It uses a whitespace-based syntax to define structure and nesting, rather than explicit tags. Key features of Pug include:
Concise Syntax: Pug uses indentation and significant whitespace to define the structure of the template. This results in cleaner, more readable code with fewer closing tags and brackets.
Mixins: Pug provides mixins, which are reusable chunks of code that can be included in templates. Mixins help in creating modular and maintainable templates by encapsulating common patterns.
Filters: Pug supports filters, which allow the transformation of text or data within the template. Filters can be used to process content such as markdown, LESS, or CoffeeScript directly within the template.
Template Inheritance: Pug supports template inheritance, where you can create a base template and extend or override specific sections in child templates. This facilitates code reuse and improves maintainability.
To render Pug, first install the pug
package from npm:
npm install pug
Now, to write code in Pug, create an index.pug
file in your views
folder and add the pug code, register Pug as the preferred template engine:
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));
In the same file, create a route that renders the file this way:
app.get('/index', (request, response) => {
response.render('index', {
subject: 'Pug template engine',
name: 'our template',
link: 'https://google.com'
});
});
The render method takes the name of the file (without the extension) and then the values of the variables in the template file.
Pug uses whitespace-based syntax to define structure and nesting, resulting in cleaner and more readable code.
doctype html
html
head
title Pug Example
body
h1 Welcome, #{username}!
if isAdmin
p You have admin privileges.
ul
each item in items
li= item
In this example, the template uses indentation to define the structure. Variables like username
are referenced using #{}
syntax. The template includes an if statement and a loop using the each
keyword to iterate over items
and generate dynamic content.
Click here to learn more about PUG.
EJS (Embedded JavaScript):
EJS is a simple and versatile template engine for JavaScript that allows embedding JavaScript code within HTML templates. It is often used in both front-end and back-end development. EJS is the most widely used Template Engine today in the industry. Here are some key features of EJS:
Syntax: EJS uses delimiter tags
<% %>
and<%= %>
to execute JavaScript code and output dynamic values, respectively. This makes it easy to embed logic and variables directly into the template.Conditionals and Loops: EJS supports control flow structures such as if-else statements and for/while loops, allowing you to create dynamic content based on conditions or iterate over data collections.
Partials: EJS provides the ability to include reusable partial templates using the included keyword, making it easier to modularize and reuse code.
Client-Side Rendering: EJS can also be used in client-side JavaScript frameworks to render templates dynamically on the browser.
To render EJS, First, install the ejs
package from npm:
npm install ejs
Next, register ejs
as the preferred template engine:
app.set('view engine', 'ejs');
Now, to write code in EJS, create an index.ejs
file in your views
folder and add the ejs code.
As said, EJS allows embedding JavaScript code within HTML templates using delimiter tags <% %>
and <%= %>
.
<!DOCTYPE html>
<html>
<head>
<title>EJS Example</title>
</head>
<body>
<h1>Welcome, <%= username %>!</h1>
<% if (isAdmin) { %>
<p>You have admin privileges.</p>
<% } %>
<ul>
<% for (let i = 0; i < items.length; i++) { %>
<li><%= items[i] %></li>
<% } %>
</ul>
</body>
</html>
In this example, the template uses <%= %>
to output dynamic values like username
and <% %>
to execute JavaScript code. The template includes a conditional statement and a loop to generate dynamic content based on the provided data.
Click here to learn more about EJS.
Handlebars:
Handlebars is a popular template engine that is based on the Mustache template language. It provides a powerful and flexible way to generate dynamic content. Key features of Handlebars include:
Logic-less Templates: Handlebars follow a logic-less approach, which means it does not support complex logic like if statements or loops within the template itself. Instead, it focuses on data interpolation and rendering.
Expressive Syntax: Handlebars use
{{}}
double curly braces to enclose placeholders and expressions. It supports variables, helpers, and partials, allowing you to customize and extend the template functionality.Helpers: Handlebars provide built-in and custom helpers to perform more complex operations within templates. Helpers enable the execution of functions, conditional checks, iteration over arrays, and other transformations.
Partials: Handlebars support partials, allowing the inclusion of reusable template fragments. Partials are useful for creating modular templates and reducing code duplication.
To render handlebars, install the hbs
package from npm
npm install hbs
Next, register hbs
as the preferred template engine:
app.set('view engine', 'hbs');
Now, to write code in hbs, create an index.hbs
file in your views
folder and add the handlebars code to it.
As said, Handlebars uses double curly braces {{}}
to enclose placeholders and expressions.
<!DOCTYPE html>
<html>
<head>
<title>Handlebars Example</title>
</head>
<body>
<h1>Welcome, {{username}}!</h1>
{{#if isAdmin}}
<p>You have admin privileges.</p>
{{/if}}
<ul>
{{#each items}}
<li>{{this}}</li>
{{/each}}
</ul>
</body>
</html>
In this example, the template uses {{}}
to interpolate dynamic values. The template includes an if statement using {{#if}}
and {{/if}}
, and a loop using {{#each}}
and {{/each}}
to generate dynamic content based on the provided data. The keyword this
represents the current item within the loop.
Click here to learn more about Handlebars.
There are many template engines available today. Click here to check the available template engines.
Each templating engine possesses its own syntax and features that cater to distinct developer preferences and project requirements. The ultimate goal of these engines is to streamline the process of generating dynamic content in web applications while promoting code reusability and maintainability.
Conclusion
Template engines are invaluable tools for creating dynamic HTML pages in server-side applications using Express.js. They are easy to set up and require minimal or no boilerplate code, allowing developers to create large applications without investing excessive time in learning the syntax.
In essence, template engines greatly enhance the development process by providing a structured and efficient approach to generating dynamic content. As a result, server-side applications become more maintainable and scalable, leading to an overall improvement in the development experience.