Getting started with Pug template engine

Watch out! This tutorial is over 6 years old. Please keep this in mind as some code snippets provided may no longer work or need modification to work on current systems.
Tutorial Difficulty Level    

Clean and organized HTML is what Front-end Developers always aim for. Well with Pug (formerly known as “Jade” ),  a high performance and feature-rich templating engine, that’s easy to achieve. Simply put, Pug is a clean, white space/indentation sensitive syntax for writing html.

Just like the programming language Python, Pug works with indentation or white spaces, like this example:

doctype html  
html(lang='en')  
 head
   title Pug
 body
   h1 Pug Examples
   div.container
     p Cool Pug example!

As you can see it’s much cleaner and easy to read than an ordinary HTML document, there are no closing tags, Pug is handling this, everything is indented and you scan the file much quicker. Also by using Pug we can ensure that our HTML is well-formed and valid.

Computer Services use Pug to generate the login page for the Xen Orchestra Dashboard, which itself is completely coded in Node.js.

Installation

To use Pug in your projects, you’ll need to install it on your Node.js server (there’s a template in XOA, but make sure you have the latest release)

$ npm install pug

and if you plan to use it at the command line

npm install pug-cli -g

You can then at any time run

$ pug --help

You can also setup Pug to be the template engine in the Express module (pre-installed on the XOA template). When initializing your Express app, you need to set it… like this:

const path = require('path')
const express = require('express')
const app = express()
app.set('view engine', 'pug')
app.set('views', path.join(__dirname, 'views'))

Syntax

As we already mentioned, Pug is a clean, whitespace sensitive syntax for writing HTML. Here is a simple example:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5)
  body
    h1 Pug - node template engine
    #container.col
      if youAreUsingPug
        p You are amazing
      else
        p Get on it!
      p.
        Pug is a terse and simple templating language with a
        strong focus on performance and powerful features.

Pug transforms the above to:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Pug</title>
    <script type="text/javascript">
      if (foo) bar(1 + 5)
    </script>
  </head>
  <body>
    <h1>Pug - node template engine</h1>
    <div id="container" class="col">
      <p>You are amazing</p>
      <p>Pug is a terse and simple templating language with a strong focus on performance and powerful features.</p>
    </div>
  </body>
</html>

API

var pug = require('pug');

// compile
var fn = pug.compile('string of pug', options);
var html = fn(locals);

// render
var html = pug.render('string of pug', merge(options, locals));

// renderFile
var html = pug.renderFile('filename.pug', merge(options, locals));

For full API, see http://pugjs.org/api/reference.html

Examples of Use

Now that you understand what Pug is and how it works with a few examples of how to use it.

Create an about view

app.get('/about', (req, res) => {
  res.render('about')
})

and the template in views/about.pug:

p Hello from ITLC

This template will create a p tag with the content Hello from ITLC.

Set variables

You can set variables in Pug templates:

- var name = 'John'
- var age = 25
- var roger = { name: 'Roger' }
- var dogs = ['Roger', 'Syd']

Loops

ul
  each color in ['Red', 'Yellow', 'Blue']
    li= color

ul
  each color, index in ['Red', 'Yellow', 'Blue']
    li= 'Color number ' + index + ': ' + color

Conditionals

if name
  h2 Hello from #{name}
else
  h2 Hello

Defining blocks

A well organized template system will define a base template, and then all the other templates extend from it.

The way a part of a template can be extended is by using blocks:

html
  head
    script(src="script.js")
    script(src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js')

    link(rel='stylesheet', href='css/main.css')
    block head
  body
    block body
      h1 Home page
      p welcome

In this case one block, body, has some content, while head does not. head is intended to be used to add additional content to the heading, while the body content is made to be overridden by other pages.

For lot’s more, see the Language Reference section at https://pugjs.org/api/getting-started.html

Interpolation with Pug

It’s important to be able to use server-side variables in your website. Pug allows you to interpolate data generated by your server in HTML, CSS, and even JavaScript code.

Interpolating variables in Pug

You can interpolate a variable using

app.get('/about', (req, res) => {
  res.render('about', { name: 'ITLC' })
})
p Hello from #{name}

Interpolate a function return value

You can interpolate a function return value using

app.get('/about', (req, res) => {
  res.render('about', { getName: () => 'ITLC' })
})
p Hello from #{getName()}

We’ll post some further, more specific tutorials on this later, but for now, please see https://pugjs.org/language/interpolation.html

Pug Ports

There are ports of Pug for use in other Programming Languages, including PHP. You can also use it in your WordPress theme development, via the Wordless plugin.

Tools

HTML To Pug is an online conversion tool for translating regular HTML into it’s equivalent Pug syntax. Very useful!