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
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
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
*/
div.container
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
router.get('/', (request, response) => {
response.render('hello', {
name: 'Aamnah',
cat: 'whiskers'
})
})
router.get('/', (request, response) => {
response.render('hello', {
name: 'Aamnah',
cat: request.query.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
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