July 17, 2024

ExpressJS: EJS Partials

In EJS template engine there is no support for inheritance like you have in Pug through block and extends keywords. So, you can't create layouts using blocks in EJS as you can in Pug template inheritance. But the functionality to include smaller files to create a larger file is very important in order to promote code reuse, making maintenance of code easier as you don't need to change code in every page. In EJS you can have the similar functionality by including smaller files to create a bigger file.

In EJS template terminology these are known as EJS partials which are reusable components that can be combined to create a larger view.

Syntax for include in EJS

You can include partial files by using the following command.

<%- include( PARTIAL_FILE ) %> 

Here PARTIAL_FILE is the file path relative to the template where partial file is included.

Note the use of <%- %> tags which allows you to output unescaped HTML content. When you use this tag <%= %>, if you have any HTML it will be rendered as string (HTML code itself) not as HTML display.

Express.js - EJS partials example

In this example we'll create an ExpressJS app where pages will have a navigation menu and footer. Since this menu and footer is common for all the pages so we can create partial files with navigation menu and footer code which can then be included in other pages which are going to be home.ejs and user.ejs.

There are also stylesheets main.css (for styling menu and footer) and user.css (for styling table which shows user data) where user.css is specific to user.ejs template.

public\css\main.css

.header{
    width: 100%;
    height: 3rem;
    text-align: center;
    background-color: #6d70a8;
    padding: 1 2rem;
    margin-bottom: 1rem;
}

.nav{
    height: 100%;
    display: flex;
    align-items: center;
}

.nav-menu{
    list-style: none;
    display: flex;
}

.nav-menu-item{
    margin: 0 2rem;
    padding: 0;
}

.nav-menu-item a{
    text-decoration: none;
    color: white;
}

.footer { 
    text-align: center;
 
    position: absolute; 
    width: 100%;
    bottom: 0; 
    left: 0; 
    background-color: #6d70a8;
    color: white;
}

public\css\user.css

table, td, th {
  border: 1px solid;
}
table {
  width: 80%;
  border-collapse: collapse;
}

Within views folder let's create a sub-folder named partials to save partial files.

views\partials\navigation.ejs

<header class="header">
  <nav class="nav">
    <ul class="nav-menu">
      <li class="nav-menu-item">
        <a href="/">Home</a></li>
      <li class="nav-menu-item">
        <a href="/user">User</a>
      </li>
    </ul>
  </nav>
</header>

views\partials\footer.ejs

<footer class="footer">
  <p>&copy; 2024 Company Name. All rights reserved.</p>
</footer>

views\home.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= pageTitle %></title>
    <link rel="stylesheet" href="/css/main.css">
  </head>
  <body>
    <%- include('partials/navigation.ejs') %>
    <h1>EJS Demo</h1>
    <p>Welcome <strong><%= userName %></strong></p>
    <%- include('partials/footer.ejs') %>
  </body>
</html>

Since navigation and footer are needed so those files are included at the appropriate location within the body.

views\user.ejs

This template is used to show user data by iterating users array. In this file also navigation and footer are needed so those files are included.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title><%= pageTitle%></title>
    <link rel="stylesheet" href="/css/user.css">
    <link rel="stylesheet" href="/css/main.css">
  </head>
  <body> 
    <%- include('partials/navigation.ejs') %>
    <h2>Using for-of to loop array</h2>
    <table>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>Gender</th>
      </tr>
      <% for(let user of users) {%>
      <tr> 
        <td><%= user.name%></td>
        <td><%= user.age%></td>
        <td><%= user.gender%></td>
      </tr>
      <%}%>
    </table>
    <%- include('partials/footer.ejs') %>
  </body>
</html>

app.js

const express = require('express');
const app = express();
const port = 3000;
const path = require('path');

// To serve static files like CSS
app.use(express.static(path.join(__dirname, 'public')));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// Hardcoded user data
const users = [{name:'Reene', age: 28, gender:'F'}, 
    {name:'Badal', age: 34, gender:'M'},
    {name:'Vidyut', age: 25, gender:'M'},
    {name:'Dhriti', age: 29, gender:'F'}
]

// for home page
app.get('/', (req, res) => {
    res.render('home', {pageTitle:'HomePage', userName:'TestUser'});
})

// for user page
app.get('/user', (req, res) => {
    res.render('user', {users: users, pageTitle: 'User Page'});
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

On running this file- node app.js and then accessing the URL- http://localhost:3000/

EJS Partials

Clicking on user menu option.

Express.js EJS partials

That's all for the topic ExpressJS: EJS Partials. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment