Koa.js - Templating



Pug is a templating engine. Templating engines are used to remove the cluttering of our server code with HTML, concatenating strings wildly to existing HTML templates. Pug is a very powerful templating engine, which has a variety of features such as filters, includes, inheritance, interpolation, etc. There is a lot of ground to cover on this.

To use Pug with Koa, we need to install it using the following command.

$ npm install --save pug koa-pug

Once pug is installed, set it as the templating engine for your app. Add the following code to your app.js file.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Now, create a new directory called views. Inside the directory, create a file named first_view.pug, and enter the following data in it.

doctype html
html
   head
      title = "Hello Pug"
   body
      p.greetings#people Hello Views!

To run this page, add the following route to your app.

_.get('/hello', getMessage); // Define routes

function *getMessage(){
   this.render('first_view');
};

You'll receive the output as −

Hello Views

What Pug does is, it converts this very simple looking markup to html. We don’t need to keep track of closing our tags, no need to use class and id keywords, rather use '.' and '#' to define them. The above code first gets converted to

<!DOCTYPE html>
<html>
   <head>
      <title>Hello Pug</title>
   </head>
    
   <body>
      <p class = "greetings" id = "people">Hello Views!</p>
   </body>
</html>

Pug is capable of doing much more than simplifying HTML markup. Let’s explore some of these features of Pug.

Simple Tags

Tags are nested according to their indentation. Like in the above example, <title> was indented within the <head> tag, so it was inside it. However, the <body> tag was on the same indentation, thus it was a sibling of <head> tag.

We don’t need to close tags. As soon as Pug encounters the next tag on the same or the outer indentation level, it closes the tag for us.

There are three methods to put text inside of a tag −

  • Space seperated −
h1 Welcome to Pug
  • Piped text −
div
   | To insert multiline text, 
   | You can use the pipe operator.
  • Block of text −
div.
   But that gets tedious if you have a lot of text. 
   You can use "." at the end of tag to denote block of text. 
   To put tags inside this block, simply enter tag in a new line and 
   indent it accordingly.

Comments

Pug uses the same syntax as JavaScript(//) for creating comments. These comments are converted to html comments(<!--comment-->). For example,

//This is a Pug comment

This comment gets converted to −

<!--This is a Pug comment-->

Attributes

To define attributes, we use a comma separated list of attributes, in parenthesis. Class and ID attributes have special representations. The following line of code covers defining attributes, classes, and id for a given html tag.

div.container.column.main#division(width = "100",height = "100")

This line of code, gets converted to −

<div class = "container column main" id = "division" width = "100" height = "100"></div>

Passing Values to Templates

When we render a Pug template, we can actually pass it a value from our route handler, which we can then use in our template. Create a new route handler with the following code.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app // equals to pug.use(app) and app.use(pug.middleware)
});

var _ = router(); //Instantiate the router

_.get('//dynamic_view', dynamicMessage); // Define routes

function *dynamicMessage(){
   this.render('dynamic', {
      name: "TutorialsPoint", 
      url:"https://www.tutorialspoint.com"
   });
};

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Then, create a new view file in the views directory, named dynamic.pug, using the following code.

html
   head
      title = name
   body
      h1 = name
      a(href = url) URL

Open localhost:3000/dynamic in your browser and following should be the output. −

Templating Variables

We can also use these passed variables within the text. To insert passed variables in between text of a tag, we use #{variableName} syntax. For example, in the above example, if we want to insert Greetings from TutorialsPoint, then we have to use the following code.

html
   head
      title = name
   body
      h1 Greetings from #{name}
      a(href = url) URL

This method of using values is called interpolation.

Conditionals

We can use conditional statements and looping constructs as well. Consider this practical example, if a user is logged in we would want to display "Hi, User" and if not, then we would want to show him a "Login/Sign Up" link. To achieve this, we can define a simple template such as −

html
   head
      title Simple template
   body
      if(user)
         h1 Hi, #{user.name}
      else
         a(href = "/sign_up") Sign Up

When we render this using our routes, and if we pass an object like −

this.render('/dynamic',{user: 
   {name: "Ayush", age: "20"}
});

It'll give a message displaying Hi, Ayush. However, if we don’t pass any object or pass one with no user key, then we will get a Sign up link.

Include and Components

Pug provides a very intuitive way to create components for a web page. For example, if you see a news website, the header with logo and categories is always fixed. Instead of copying that to every view, we can use an include. Following example shows how we can use an include −

Create three views with the following code −

header.pug

div.header.
   I'm the header for this website.

content.pug

html
   head
      title Simple template
   body
      include ./header.pug
      h3 I'm the main content
      include ./footer.pug

footer.pug

div.footer.
   I'm the footer for this website.

Create a route for this as follows.

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

_.get('/components', getComponents);

function *getComponents(){
   this.render('content.pug');
}

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

Go to localhost:3000/components, you should get the following output.

Templating Components

include can also be used to include plaintext, CSS and JavaScript.

There are many other features of Pug. However, those are out of the scope for this tutorial. You can further explore Pug at Pug.

Advertisements