Intro to Templating with Pug (previously known as Jade)

  • Pug is a templating engine for Node.js
  • Hierarchy is defined with indentation
  • Pug let’s you use JS inside the templates. You can loop and use logic. You can also do mixins and advanced templating
  • Pug is white-space sensitive. The pipe | character is used for whitespace control For example, if you want to start your content on a new line, it’ll treat the first word as a tag. So you use | at the beginning to avoid that. A dot . is also used
doctype html
		title= pageTitle
			if (foo) bar(1 + 5)
	//- This comment will only show inside the template, will NOt be rendered with HTML
	// This comment will be rendered in HTML

		h1.title you just rendered a Pug template!
			- const youAreUsingPug = true //- Locally defined varaible

			if youAreUsingPug
				p You are amazing!
				p Looks like you don't used Pug. Get on it!
				Pug is a terse and simple templating language with a 
				strong focus on performance and powerful features. Here is some #[strong bold text] and here's some #[em italic text].

			- const name = "Jake". toUpperCase(); //- Locally defined variable with some more JS

			| You can have local variables as well as have data passed down via the render function. For example, my name is: #{name}

			p #{name} has a cat named #[strong #{cat}]

Getting started

npm i -S pug pug-cli

Usage in Express

Set Pug as your view engine
const app = require('express')
// app.set('views', location_for_your_views_dir)
app.set('views', path.join(__dirname, 'views')) // define views dir
app.set('view engine', 'pug') // define view engine for .render()
Rendering a Pug template
const router = express.Router()
router.get('/', (request, response) => {
  response.render('hello') // a template file in views dir, no need for file extension
Sample Pug template
  h1.title You just rendered a Pug template!
  • For divs, you don’t need to explicitly say it’s a div, just mentioning the divs and classes will do since it’ll assume by default that the block is a div (i.e. div.container and .container are the same)

classes and IDs

  h1.title This is an H1 heading with a class of `.title` inside a `div.container`
  span#attention This is a span with the ID `#attention`
    p.copy.class.anotherclass This is a p tag inside the span tag with multiple classes

attributes and values

  • attributes go in parantheses ()

Here’s a div.container containing an image

  img(src="dog.jpeg" alt="Dog")

You can of course assign both classes and attributes like so"dog.jpeg" alt="Dog")

Here is an input field with attributes specified on multiple lines, works just fine



  • // will output in markup
  • //- will be hidden in HTML markup, is for use within Pug templates only

strong and em text

  • You’ll use what’s called Tag Interpolation
  • #[strong word] and #[em word] is the syntax
p #{name} has a cat named #[strong #{cat}]
  This is a very long and boring paragraph that spans multiple lines.
  Suddenly there is a #[strong strongly worded phrase] that cannot be
  #[em ignored].
  And here's an example of an interpolated tag with an attribute:
  #[q(lang="es") ¡Hola Mundo!]

Passing data to your templates

  • Data is passed as the second argument when you’re rendering your template with the render() function (the first argument is the template file name).
  • #{} is used to interpolate variables inside templates
router.get('/', (request, response) => {
  response.render('hello', {
    name: 'Aamnah',
    cat: 'whiskers'
router.get('/', (request, response) => {
  response.render('hello', {
    name: 'Aamnah',
    cat: // make it dynamic, pass the cat's name as a URL query
p #{name} has a cat named #{cat}

Declaring variables inside templates

  • start the line with a -
- const city = "Lahore".toUpperCase();

p I live in #{city} //- I live in LAHORE

Putting variables inside attributes

  • You use a JS template literal, ES6 style"dog.jpg" alt="Dog `${dog}`")


  • Blocks are sections that can be filled in by other templates
  • You both define and overwrite a block with the block keyword
	block header

	  block content

extending layout

extends layout

block content
  p This is some content