Notes

Intro to Templating with Pug (previously known as Jade)

intro to Pug templates in Express, with classes, attributes, comments, tag interpolation, passing data, blocks and extends

Edit on GitHub


Node
4 minutes
  • 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
html(lang="en")
	head
		title= pageTitle
		script(type='text/javascript').
			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

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

			if youAreUsingPug
				p You are amazing!
			else
				p Looks like you don't used Pug. Get on it!
			p.
				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

			p
			| 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

1npm i -S pug pug-cli

Usage in Express

1/*
2Set Pug as your view engine
3*/
4const app = require('express')
5// app.set('views', location_for_your_views_dir)
6app.set('views', path.join(__dirname, 'views')) // define views dir
7app.set('view engine', 'pug') // define view engine for .render()
1/*
2Rendering a Pug template
3*/
4const router = express.Router()
5router.get('/', (request, response) => {
6  response.render('hello') // a template file in views dir, no need for file extension
7})
1/*
2Sample Pug template
3*/ 
4div.container
5  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

.container
  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

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

You can of course assign both classes and attributes like so

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

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

input(
  type='checkbox'
  name='agreement'
  checked
)

comments

  • // 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}]
p.
  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].
p.
  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
1router.get('/', (request, response) => {
2  response.render('hello', {
3    name: 'Aamnah',
4    cat: 'whiskers'
5  })
6})
1router.get('/', (request, response) => {
2  response.render('hello', {
3    name: 'Aamnah',
4    cat: request.query.cat // make it dynamic, pass the cat's name as a URL query
5  })
6})
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
img.dog(src="dog.jpg" alt="Dog `${dog}`")

Blocks

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

	.content
	  block content

extending layout

extends layout

block content
  p This is some content

Related

Browse all topics