Node.js app with Nunjucks (Part 5)

So far, we have built the basic Node.js app, configured Nunjucks, learned about template inheritance, and Nunjucks tags for basic operations like creating and modifying variables, conditional statements, and loops. This time, we will learn how to create macros to avoid code repetition.

Creating a macro

Macros in Nunjucks are like functions in a programming language. To create one, you need the macro tag, which has the name of the macro and its parameters if required, and the closing tag endmacro. The logic goes between the two tags. Here is an example of a simple macro that provides a greeting text depending on the day of the week.

The parameters to the macro can have default values to use if the values are not provided in the macro call (for more details, see the documentation). An example of that in the following macro is the value for the target attribute of the html anchor tag.

At this point in the tutorial, you should be able to understand the above code, though some parts require explanation. First is the following line:

It uses a replace filter. Filters, as explained in the Nunjucks documentation, are functions that can be applied to variables, are called with a pipe operator, and can take arguments. In this case, it replaces the route parameters with the provided values.

Another line that requires some explanation is

It uses one of the few special variables that are provided with the for loop: loop.first, which is a boolean indicating the first iteration.

Using a macro

To use a macro, you have to import it into a template.

Then you can use it for variable assignment

or directly in a block of code.

Happy coding!

Node.js app with Nunjucks (Part 4)

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.

Prerequisities

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

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,

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

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.

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

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.

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.

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!

Node.js app with Nunjucks (Part 3)

After building the basic Node.js app and configuring Nunjucks, we have everything ready and can start creating individual pages and learning about inheritance.

Template inheritance

First, you should create some subdirectories in the views directory to logically structure the templates. You need layouts where you keep the templates containing the overall page structure. Move the index.njk file there. You also need partials, where you will keep templates of the elements that are common to all or most pages, like the header and footer. And finally, you also need a mainContent directory where you will keep templates of the individual pages main content.

Once that’s done, open the index.njk file and start moving its parts to their own template files. In the partials directory, create a head.njk file and move the head section there. Then use the include tag to add it to the index.njk so that every time the latter is rendered, the content of the former will be pulled in exactly in the place where the include tag is placed.

It has to be inside {% %} since Nunjucks uses specific tokens to enclose variables, blocks, and comments (this is actually configurable; for details, see the customising syntax section of the documentation).

Next, create a file named home.njk in the mainContent directory and move to it the <h1> header from index.njk. However, this time instead of including the new partial template in the index.njk, add a <main> element to the <body>, and inside it create a new block tag with the mainContent identifier. It also requires a closing tag indicating the end of the block.

Then in home.njk, enclose the <h1> header in a block with the same identifier and make this partial template a child of index.njk, using the extends tag. This will cause the mainContent block in parent to be overwritten during rendering by the one in child. But you can also render the contents of the parent block inside a child block by calling the special function super() (check the documentation for details).

Once this is done, your project structure should look like this:

Happy coding!

Node.js app with Nunjucks (Part 2)

In the first part of this tutorial, we created a basic Node.js app to use for serving pages built using Nunjucks. Now it’s time to configure Nunjucks and our app to use it.

Configuration

Firstly, install Nunjucks, and to use the file watcher built-in to Nunjucks, Chokidar, a cross-platform file-watching library, must be installed as well.

You have to also install the relevant type definition package.

Following the model-view-controller software design pattern, create a views subdirectory in the src directory. This is where your template files will be located. Then in the index.ts file set path to it.

Also remember about importing the Node.js path module (here is more about it if you are interested in details).

Next, create a Nunjucks loader, which is an object that takes a template name and loads it from a source, with a path to templates as an argument.

Also, create an object with the loader options. You really only need two: watch, which reloads templates when they are changed (server-side), and noCache, which will determine if the cache is used or templates will be recompiled every single time (see the documentation).

Of course, remember to add relevant entries to the .env file.

Finally, create a new instance of Nunjucks’s Environment class with the loader and its options.

Then install Nunjucks as the rendering engine for the Express app.

You also need to provide the view engine, which is the file extension of your template files. You can use njk, which is the one adopted by the Nunjucks community, or html, but in fact, you are free to use any file extension you wish for your Nunjucks template files since any will work.

To check if the configuration works, create a simple template in the views directory with the name index.njk.

Then create a controllers directory in the src directory, and inside it, create an indexController.ts file with a simple function that will call Nunjucks’s render function available in the response parameter. It takes the name of the template and an object with properties that will be used in the template to substitute the tags with the provided texts. You have to ensure that the property keys are the same as the tags in the template.

Next, you have to import it into index.ts

and provide as a parameter to the get request instead of the previously used arrow function.

Before you can run the app, you have to modify the scripts in package.json. First, add a new script called build that will run the preexisting clean script, which removes the build directory, then the compile script, which will run the TypeScript Compiler (tsc), and finally copy recursively the views directory.

Then modify the start script, replacing the compile script with the build script, so it’s as follows:

Now you can run your app. Happy coding!

Node.js app with Nunjucks (Part 1)

The main focus of this tutorial is to learn how to use Nunjucks, a powerful templating language for JavaScript. However, before we can dive into Nunjucks itself, it is first important to create a basic Node.js app to use for serving pages built using Nunjucks. Thus, this is what the first part of this tutorial is all about.

Creating a basic Node.js app

To create a Node.js app, first create a new project directory and enter it.

The next step is optional, although it is always good idea to use version control, even if only for practice.

Once that’s done, initiate a new npm package using npm, the default package manager for Node.js. If you add the -y flag, it will use the default values as explained in this blog post.

To further save time and effort, install Google TypeScript Style (GTS), which will allow you to automatically set up a simple TypeScript project while providing a style guide, a linter, and automatic code correction.

Then initialise TypeScript project using GTS.

This will create all the configuration files with the basic default configuration for TypeScript and Lint. To further tune the project, add to the compilerOptions in tsconfig.json the following options:

The first one specifies ECMAScript target version, the second one sets the module system for the program, the third one fixes some problems with imports and the last one prevents TypeScript from assuming type any if type annotation is not present. For reference see the documentation available at https://www.typescriptlang.org/tsconfig.

Next install ts-node, which is a TypeScript execution engine and REPL for Node.js

and add start script to package.json

For convenience, also install nodemon, a tool that will help develop your node application by automatically restarting it when file changes are detected

and add the relevant script to the package.json

Now you can run your basic app from the terminal with either npm start or npm run start:dev. But before you do that, replace the default content of the src/index.ts file with the following code:

You have to also install a web framework for Node.js called Express and Dotenv, a module that loads environment variables from a .env file into process.env, and type definition packages

and add a .env file in the root directory of the project with the PORT variable set

Now all is ready. Happy coding!