EJS is a simple templating language that lets you generate HTML markup with plain JavaScript.

Install

npm install ejs



Examples

<%= pageTitle %>  //render pageTitle variable
<%- include('includes/head.ejs') //render html/ejs file %>
<% if (prods.length > 0) { %> //for loop



Routes - using Router and Path - Serving HTML pages

-routes
    |
    |---admin.js
    |---shop.js
-views
    |
    |---includes
    |       |
    |       |---head.ejs
    |       |---navigation.ejs
    |
    |---shop.ejs
    |---add-product.ejs
-util
    |
    |---path.js
-public
    |
    |---css
        |
        |---main.css
-app.js



util/path.js

const path = require('path');
module.exports = path.dirname(process.mainModule.filename);



routes/admin.js

const path = require('path');
const express = require('express');
const router = express.Router()
const rootDir = require('../util/path'); //if we want to use path to dirname above

const products = [];

router.get('/add-product', (req, res, next) => {
    res.render('add-product', {
        pageTitle: 'Add product',
        path: '/admin/add-product',
        activeAddProduct: true
    });
});

//this will trigger for only POST requests
router.post('/add-product', (req, res, next) => {
    console.log(req.body);  //req.body is available because of using bodyParser
    products.push({ title: req.body.title });
    res.redirect('/');
});

exports.routes = router;
exports.products = products;



routes/shop.js

const path = require('path');
const express = require('express');
const router = express.Router();
const adminData = require('./admin');

router.get('/', (req, res, next) => {
    const products = adminData.products;
    res.render('shop', {
        prods: products,
        pageTitle: 'shop',
        path: '/',
        hasProducts: products.length > 0,
        activeShop: true
    });
});
module.exports = router;



views/includes/head.ejs

<!DOCTYPE html>
<html>
<head>
    <!-- we are using express.static in app.js to serve static css file from public dir -->
    <link rel="stylesheet" href="/css/main.css">



views/includes/navigation.ejs

<header>
    <nav>
        <ul>
            <li><a class="<%= path === '/' ? 'active' : '' %>" href="/">Shop</a></li>
            <li><a class="<%= path === '/admin/add-product' ? 'active' : '' %>" href="/admin/add-product">Add product</a></li>
        </ul>
    </nav>
</header>



views/add-product.ejs

<%- include('includes/head.ejs') %>
</head>
</head>
<body>
    <%- include('includes/navigation.ejs') %>

    <main>
        <form action="/admin/add-product" method="post">
            <input type="text" name="title">
            <button type="submit">Add product</button>
        </form>
    </main>
</body>
</html>



views/404.ejs

<%- include('includes/head.ejs') %>
</head>
<body>
    <%- include('includes/navigation.ejs') %>
    <h1>Page not found</h1>
</body>
</html>



views/shop.ejs

<%- include('includes/head.ejs') %>
</head>
</head>
<body>
    <%- include('includes/navigation.ejs') %>
    <main>
        <% if (prods.length > 0) { %>
            //render products
            <% for (let product of prods) { %>
                 <div>
                    <%= product.title %>
                 </div>
            <% } %>
        <% } else { %>
            <h1>No products found</h1>
        <% }  %>
    </main>
</body>
</html>



app.js

const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

//set template engine to EJS
app.set('view engine', 'ejs');
app.set('views', 'views');

const adminData = require('./routes/admin');
const shopRoutes = require('./routes/shop');

app.use(bodyParser.urlencoded({exteneded: false}));

//add this to make public folder available to serve static files, like css
app.use(express.static(path.joing(__dirname, 'public')));

app.use('/admin', adminData.routes);
app.use(shopRoutes);

//404 error page, when i make request to path which doesnt exists
app.use((req, res, next) => {
    res.status(404).render('404', { pageTitle: 'Page Not Found' });
});

app.listen(3000);