Where to Discuss?

Local Group

Preface

Goal: Feeding Data in ExpressJS, and Process in a Loop with Nunjucks.

Consider continue with nunjucks example.

Official Documentation

Source Examples

You can obtain source examples here:


Nunjucks Case

The nunjucks case is the same, with the one utilizing grunt in previous article with a few differences.

  • express configuration

  • Using data to provide hyperlink in both navbar and sidebar.

Directory Structure

Consider an express structure with nunjucks views.

❯ tree
.
├── app.js
├── package.json
├── public
│   ├── css
│   │   └── w3.css
│   ├── favicon.ico
│   └── js
│       └── script.js
└── views
    ├── css.njk
    ├── html.njk
    ├── index.njk
    ├── javascript.njk
    ├── partials
    │   ├── head.njk
    │   ├── layout.njk
    │   ├── navbar.njk
    │   └── sidebar.njk
    └── php.njk

5 directories, 14 files

Nunjucks: Example: Tree

The views structure is similar to previous case with grunt. I suggest that you have fast reading for this article first.

package.json

All you need to know is the devDependencies.

  "devDependencies": {
    "express": "^4.17.1",
    "nunjucks": "^3.2.1"
  }

To begin with expressjs, you need to run npm install first.

app.js

You also need to a write a simple application in app.js.

// Basic Stuff
var express = require('express');
var path = require('path');
var app = express();

app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.locals.pretty = true;

// Nunjucks Configuration
var nunjucks  = require('nunjucks');
app.engine('.njk', nunjucks.render);
app.set('view engine', 'njk');

nunjucks.configure('views', {
  autoescape: true,
  watch     : true,
  express   : app
});

// Example Pages
var pages = [
  { link: '/',     short: 'Home', long: 'Home'  },
  { link: '/html', short: 'HTML', long: 'HTML Link' },
  { link: '/css',  short: 'CSS',  long: 'CSS Link' },
  { link: '/php',  short: 'PHP',  long: 'PHP Link' },
  { link: '/javascript', short: 'Javascript', long: 'Javascript Link' }
];

// Router
app.get('/', function(req, res) {
  res.render('index', { pages: pages });
  console.log("choice page is index");
});

const choices = ['index', 'html', 'css', 'php', 'javascript'];
app.get('/:page', function(req, res) {
  page = req.params.page;
  
  if (choices.includes(page)) {
    res.render(page, { pages: pages });
    console.log("choice page is " +page);
  } else {
    res.send('404: Page not Found', 404);
  }
});

// Run, Baby Run
app.listen(3000);
console.log('Express started on port 3000');

The application is short enough to be self explanatory.

Nunjucks Template Specific Code

Different with the pug example, we need a longer configuration for nunjucks.

var nunjucks  = require('nunjucks');
app.engine('.njk', nunjucks.render);
app.set('view engine', 'njk');

nunjucks.configure('views', {
  autoescape: true,
  watch     : true,
  express   : app
});

The same for every templates

To provide hyperlink in both navbar and sidebar, we need to setup the data in app.js as below:

var pages = [
  { link: '/',     short: 'Home', long: 'Home'  },
  { link: '/html', short: 'HTML', long: 'HTML Link' },
  { link: '/css',  short: 'CSS',  long: 'CSS Link' },
  { link: '/php',  short: 'PHP',  long: 'PHP Link' },
  { link: '/javascript', short: 'Javascript', long: 'Javascript Link' }
];

We will feed the data for each request.

app.get('/', function(req, res) {
  res.render('index', { pages: pages });
  console.log("choice page is index");
});

The sidebar will use long text, and the navbar will use short one.

Router

The same for every templates

For simplicity, I put all the routes in app.js.

app.get('/', function(req, res) {
  res.render('index', { pages: pages });
  console.log("choice page is index");
});

const choices = ['index', 'html', 'css', 'php', 'javascript'];
app.get('/:page', function(req, res) {
  page = req.params.page;
  
  if (choices.includes(page)) {
    res.render(page, { pages: pages });
    console.log("choice page is " +page);
  } else {
    res.send('404: Page not Found', 404);
  }
});

If the request does not contain any of the above page, express will send 404 error response.

Loop in Template

This time, consider alter a bit, both the sidebar and the navbar, so we can render each data in loop.

  <div class="w3-sidebar w3-bar-block w3-card w3-animate-left" 
       style="display:none" id="mySidebar">
    <button class="w3-bar-item w3-button w3-large"
       id="closeNav" >Close &times;</button>
    {% for page in pages %}
      <a class="w3-bar-item w3-button"
         href="{{ page.link }}">{{ page.long }}</a>
    {% endfor %}
  </div>
    <div class="w3-teal">
      <button class="w3-button w3-teal w3-xlarge"
              id="openNav">&#9776;</button>
      <div class="w3-container">
        <h1>My Page</h1>
      </div>
    </div>

    <div class="w3-bar w3-black">
    {% for page in pages %}
      <a class="w3-bar-item w3-button"
         href="{{ page.link }}">{{ page.short }}</a>
    {% endfor %}
    </div>

All you need to know is these lines:

    {% for page in pages %}
      <a class="w3-bar-item w3-button"
         href="{{ page.link }}">{{ page.short }}</a>
    {% endfor %}

Express: Loop in Nunjucks

This will render a hyperlink, with result about the same with previous example.

Running Express

Running express is as easy as this command below.

$ node app.js

HTML: Hyperlink Example

Click any hyperlink on the example case, and you will get the response in console.log immediately.

Express: node app.js

You are ready to run a website, with expressjs backend, using nunjucks.


What’s Next?

We still have two expressexample:EJSandhandlebars`. Consider continue reading [ Template - Express - EJS ].