Node.js app with Nunjucks (Part 4)

Maciej Modzelewski
Version 1
Published in
4 min readFeb 25, 2024

So far, we have built the basic Node.js app, configured Nunjucks, and learned about template inheritance. Now we can start creating additional parts of the page template in their own files and learn more Nunjucks tags while creating their content.

Prerequisites

First, create three additional templates in the partials directory: header.njk, navbar.njk, and footer.njk, and include them in the index.njk.

<!DOCTYPE html>
<html lang="en">
{% include "partials/head.njk" %}
<body>
{% include "partials/header.njk" %}
{% include "partials/navbar.njk" %}
<main>
{% block mainContent %}{% endblock %}
</main>
{% include "partials/footer.njk" %}
</body>
</html>

We also need to style our content, so for that, create a directory called public in the project root directory and inside it a styles subdirectory with a style.css file in it. Then add a link to that file in the head.njk,

modify the build script in package.json to copy the public directory,

"build": "npm run clean && npm run compile && cp -r src/views build/src/views && cp -r public build/public"

and add the relevant entry in index.ts to serve static files.

app.use(express.static(path.join(__dirname, '../public')));

Basic operations

Let’s start learning the basic operations that you are guaranteed to use on a daily basis.

Creating and modifying variables

To create or modify a variable in Nunjucks, you have to use the set tag. Let’s say that you wish the text in <title> to be a concatenation of two texts: one provided as a global variable and another being the particular page header. For that, provide the global variable in the index.ts as follows.

nunjucksEnvironment.addGlobal('titleMainText', 'My Website');

Then in the head.njk above the <head> tag sets the titleText variable that was previously provided by the indexController,

{% set titleText = titleMainText + " - " + headerText %}

and, of course, you have to remove the relevant entry from that controller, so now it will only provide the headerText.

If you are in a situation where you have to capture a whole block of content into a variable, there is an alternative syntax that uses the closing tag {% endset %}, like in this code that we add to the header.njk

Since by default Nunjucks will escape all output, if not configured differently, the above code would render the headerLink into a string instead of an actual hyperlink, so to avoid that, you have to mark it as safe. Remember also to update the indexController that provides the data for the Nunjucks template.

Conditional statements

The if statement in Nunjucks behaves exactly as if in JavaScript, but unlike in the latter, it requires a closing endif tag. Also, the else if statement has the form elif or elseif, which is simply an alias of elif. Here is an example of how to use it: In home.njk it takes a weekday variable provided by the indexController and sets a greeting text based on a particular condition. The result is used in a paragraph in the mainContent block.

{% if weekDay === "Friday" %}
{% set greetingText = "It's almost the weekend." %}
{% elif weekDay === "Saturday" or weekDay === "Sunday" %}
{% set greetingText = "Enjoy your weekend break." %}
{% else %}
{% set greetingText = "It's just another working day." %}
{% endif %}

{% block mainContent %}
<p>Today is {{ weekDay }}. {{ greetingText }}</p>
{% endblock %}

Similar to the ternary operator, you can use if as if it were an inline expression.

For loop

The for loop iterates over arrays and dictionaries, and just like the if statement, it requires a closing tag. If you wish to iterate over an array, the syntax is “for item in array,” and in the case of a dictionary, it is “for key, value in dictionary.” Let’s look at an example. We will create a simple navbar. The text and href of each element will come in a dictionary created in the indexController.

const menu: Map<string, string> = new Map();
menu.set('Home', '/');
menu.set('Texts', '/texts');
menu.set('Gallery', '/gallery');
menu.set('About', '/about');

res.render('mainContent/home', {
headerText: 'Hello World!',
headerHref: '/',
weekDay: weekDay,
menu: menu,
});

Then in navbar.njk, we create a <nav> element with a list inside, which is populated using the for loop and the menu dictionary.

Add styles to your liking and you’re done. Happy coding!
If you’re interested in how these skills can be applied to larger projects, be sure to check out our Azure Application Modernisation Playbook.

About the author

Maciej Modzelewski is a Java Developer at Version 1.

Originally published at http://maciejmodzelewski.com on February 25, 2024.

--

--