Introduction to EJS: A Guide to Building Dynamic Web Applications
Tags: node, express, webdev, javascript
Published: 2023-02-14 23:57:09

## Introduction

Embedded JavaScript, or EJS, is a simple and direct templating language that enables JavaScript to generate HTML. It's frequently used in Express.js, a Node.js framework for creating web applications, but it can also be used in other JavaScript environments. 

This article will cover the fundamentals of EJS and how to utilize EJS to build dynamic web applications.

## **Installation**

To use EJS, you'll need to have Node.js and npm (Node Package Manager) installed on your computer. Once that's done, you can create a new Node.js project by running the following command in your terminal:

```bash
npm init -y
```

This will also create a new **`package.json`** file in the root directory of your project, which you can use to manage your dependencies.

To continue, you will have to install the Express and EJS packages by entering the following npm commands also in your terminal:

```bash
npm install express # install express
# and
npm install ejs # install ejs
```

This will add Express and EJS as dependencies to your project’s **`package.json`**.

## How Do EJS Templates Look?

EJS templates have additional unique tags that let you include dynamic content, but they still look similar to regular HTML files. This makes EJS templates a fantastic option because anyone familiar with HTML can easily understand and work with them.

Examples of these extra tags are:

- **`<%`** and **`%>`**: These tags allow JavaScript code to run without outputting anything to the template. For example, you can use these tags to define variables or call functions.
- **`<%=`** and **`%>`**: These tags are used to output the result of a JavaScript expression to the template. For example, you can use these tags to insert data into the template.
- **`<%-`** and **`%>`**: These tags are used to output the result of a JavaScript expression to the template. However, unlike **`<%=`** and **`%>`** tags, they do not escape the output.
- **`<%#`** and **`%>`**: These tags add template comments.

Here's an example of what an EJS template looks like:

```html
<!DOCTYPE html>
<html>
<head>
  <title>My List</title>
</head>
<body>
  <% var message = "Hello, World!"; %>
  <h1><%= message %></h1>
  <%# This is a comment; it will not be included in the final output %>
  <% if (items.length === 0) { %>
    <p>No items to display.</p>
  <% } %>
</body>
</html>
```

As you progress through the article, you will learn how to utilize these tags in your code.

## **Setting Up EJS in Express.js**

To set up EJS in Express.js, first, require the **`express`** module to initialize an Express.js app. Then, set **`ejs`** as the view engine using the **`app.set()`** method:

```jsx
const express = require('express');
const app = express();

// Setting EJS as the view engine
app.set('view engine', 'ejs');

//Server is listening on port 5000
app.listen(5000, () => {
    console.log(`App listening at port 5000`);
  })
```

After setting the **`view engine`** to **`ejs`**, you can now create a new folder in the root directory of your project called **`views`** and add your EJS templates there. 

<aside>
💡 It's important to remember that EJS always looks for templates in the **`views`** directory. As a result, it is critical that you always keep your templates in this directory so that the EJS engine can find and process them.

</aside>

For example, An **`index.ejs`** in your **`views`** folder will be rendered using the following code in a route:

```jsx
const express = require('express');
const app = express();

app.set('view engine', 'ejs');

//Rendering index.ejs 
app.get('/', (req, res) => {
    res.render('index');
});

app.listen(5000, () => {
    console.log(`App listening at port 5000`);
  })
```

The **`render`** function, provided by Express, will look for a template with the same name as the first argument you pass to it in the **`views`** folder that is **`index`** and renders it when the root route is accessed using the view engine you set up earlier.

## **Passing Data to EJS Templates**

EJS can pass data to templates and use that data to generate dynamic HTML. You can pass data to a template by providing an object as the second argument to the **`render`** function. For instance, let's say you want to pass a variable called **`name`** to your **`index.ejs`** template:

```jsx
app.get('/', (req, res) => {
    res.render('index', { name: 'Alice' });
});
```

You can use the variable in your **`index.ejs`** template in this way:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS FOR BEGINNERS</title>
</head>
<body>
    <h1>Hello <%= name %>!</h1>   
</body>
</html>
```

When the template is rendered, that is, when the script is executed, the **`name`** variable will be replaced with the value(**Alice**) passed to the **`render`** function.

## Using EJS to Include Reusable Template Components

EJS also allows you to combine different templates for different sections of your code, like your head, header, and footer sections.

You can add **`.ejs`** files to a current template using the **`<%- include (’file.ejs’) %>`** statement. 

For example, if you have a template called **`header.ejs`** that you want to include in your **`index.ejs`** template, you can use the following code

in your **`index.ejs`** template:

```html
// header.ejs
<header>
    <nav>
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
            <li><a href="/contact">Contact</a></li>
        </ul>
    </nav>
    <h1>My Website</h1>
</header>
```

```html
// index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS FOR BEGINNERS</title>
</head>
<body>
		<header>
					<%- include ('header.ejs') %>
		</header>
    <h1>Hello <%= name %>!</h1>   
</body>
</html>
```

This will include the contents of the **`header.ejs`** template to that point in the **`index.ejs`** template. 

It is common practice to save templates that you will want to reuse across multiple pages in a **`partials`** subdirectory in the views directory.

To include the header in your code after doing this, attach the file path to the former syntax:

```html
<%- include ('partials/header') %>
```

The `**<%- include %>**` tag makes it simple to reuse common HTML elements across multiple pages or views, simplifies code maintenance, and preserves a consistent look across your application.

## Iterating Over Data in EJS

EJS also allows you to use JavaScript's looping statements to generate dynamic HTML. To understand this better, update your express app to hold some array containing data. For example:

```jsx
const express = require('express');
const app = express();

app.set('view engine', 'ejs');

//Rendering index.ejs 
app.get('/', (req, res) => {
    res.render('index');
});

app.listen(5000, () => {
    console.log(`App listening at port 5000`);
  })
```

Then, update your `**index.ejs**` file to display the array:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS FOR BEGINNERS</title>
</head>
<body>
		<header>
					<%- include ('header.ejs') %>
		</header>
    <h1>Hello <%= name %>!</h1>   
    <ul>
    <% for (let i = 0; i < data.length; i++) { %>
        <li><%= data[i] %></li>
    <% } %>
    </ul>
</body>
</html>
```

In this code block, the **`<%…%>`** EJS tag is used to incorporate pure JavaScript into the template; this JavaScript takes the form of a for loop that iterates over the elements in the **`data`** array. Each element of the array is displayed using the **`<li>`** tag, with the EJS expression **`<%= data[i] %>`** used to output the value of the **`data[i]`** variable.

## Conditional Statements in EJS

You can also use JavaScript conditional statements to make your express app more dynamic. With conditional statements like **`if..else`** statements, You can choose to display some part of your app or not. That's the power of being dynamic given to you by EJS!

To understand how to use the if-else JavaScript statement to conditionally render certain parts of the template, set up your express app to contain a variable **`numberOfNames`**. For example:

```jsx
const express = require('express');
const app = express();

//Adding test data 
const data = ["ada", "abba", "goodness", "david", "patrick"]

//Setting the view engine to ejs
app.set('view engine', 'ejs');

let numberOfNames = data.length;

//Rendering index.ejs 
app.get('/', (req, res) => {
    res.render('index', {name:"Alice", data : data, numberOfNames: numberOfNames});
});

app.listen(5000, () => {
    console.log(`App listening at port 5000`);
  })

```

The variable **`numberOfNames`** created below the for loop saves the number of elements in the data array. Then, update your **`index.ejs`** file to perform an action based on some condition about the **`numberOfNames`** variable.

Like so:

```html
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS FOR BEGINNERS</title>
</head>
<body>
		<header>
					<%- include ('header.ejs') %>
		</header>
    <h1>Hello <%= name %>!</h1>   
    <ul>
    <% for (let i = 0; i < data.length; i++) { %>
        <li><%= data[i] %></li>
    <% } %>
    </ul>
    <% if (numberOfNames >= 5) {%>
        <p> There are at least 5 people on the list </p>
    <% } else { %>
        <p> There are less than 5 people on the list</p>
    <% } %>
</body>
</html>
```

The if statement in this code block displays information about the number of names conditionally. The EJS tags surrounding the if statement control the JavaScript flow and allow the code to make decisions based on specified conditions.

You can also see how the displayed information changes when you reduce the number of elements in the data array to less than 5. This demonstrates how EJS can dynamically adjust the output based on the input data.

## Conclusion

EJS is a simple and powerful templating language that allows you to generate dynamic HTML using JavaScript. It is easy to set up and use and is an excellent choice for building web applications with Node.js and Express.js. By understanding the basics of EJS, including how to pass data to templates, include other templates, and use looping and conditional statements, you can build more dynamic and interactive web applications.