A rude awakening

In the river of yellow umbrellas,
the rain swims with frantic crawls,
as if plotting wet shoulders were barely enough.
But even if the sky forgives the reflection
and the wind forgets the manner,
once they learn that forever has a pretty short shelf life,
they will realise all that’s left is to count
the grains of sand stolen from an hourglass
and be cautious.

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!

Journal (The gift of life)

I never asked to be born. It was forced upon me by a moment of mindless lust, later sugarcoated by religion with the phrase “the gift of life.” The problem is, unlike an unwanted Christmas gift, I can’t simply toss it away. Both nature and society have made sure to hold me hostage as long as possible and to produce further victims of this vicious circle. Now that I’ve finally realised this, I know why Merry Christmas sounds like an insult.

Journal (Leave the story where it ended)

I promised myself that I would write something in this journal every day. That’s why I call it a journal and not a diary. But yesterday I got so into the anime series that I couldn’t stop watching it until I watched the entire first season. It’s called Horimiya. I’ve seen it at least three times this past winter, when I had a period of fascination with the anime genre and watched nothing but anime for about six months. I have to admit, I like it just as much as I did when I first saw it.

Later, in the evening

So, I finished watching the second season, which is new, and I’m disappointed. Not that it was bad, but I expected something different—a continuation or something along this line. Instead, it was like watching footnotes to the first season or miscellaneous. I think sometimes it’s better to leave a story where it originally ended rather than try to squeeze some extra cash out of it with artificial prolongations.

Journal (The world of the one percent)

I have always had this funny feeling that when someone accuses remote workers that they “don’t work as hard,” there is more to it. But it’s not rocket science to figure out what’s behind such words coming from the mouth of someone like Steve Schwarzman, the boss of the world’s biggest commercial landlord—it’s money. It’s always money. Welcome to the world of the one percent. I bet Mr. Schwarzman doesn’t give a damn about the productivity of those working from home. The only thing he cares about is the hard cash that he loses when his office buildings are empty because no one needs to rent them if the staff of many companies work remotely. And just so you know, Mr. Schwarzman, not only do we work as hard, but we are actually more productive when finally free from all the unnecessary distractions inherent in the office. But that would be enough about Mr. Schwarzman. He doesn’t deserve even that much airtime.

Journal (I’m a city dweller)

I watched Jenny’s Wedding today. Nothing special, really. Apart from the fact that it’s about a lesbian couple, it’s just another romcom spiced with a pinch of light drama. But there was one thing there that made me think. The protagonist’s sister, played by Grace Gummer, realises that the grass in front of her house is always dead, and then she has an epiphany: “Happy people do not have dead grass.” It ends badly for her husband (not that I pity him—he was rather obnoxious). The problem is that I hate grass. Not in general, as there is nothing more pleasant than a stroll on the meadow in summer, but the lawn in front of the house is the essence of artificiality. I hate Saturday gymnastics with a lawnmower and the endless fight with moss and so-called weeds. When I lived in a house with a lawn, I envied my neighbour’s elegantly tiled front yard. But does this make me a bad person, a social outcast, or a less desirable life partner? I’m a city dweller, that’s all. Suburbs are not for me.