Pug templates

Everything you need to start

in a nutshell!

contents

01

What is

02

Install

03

The basics

04

Examples

05

Tricks

06

Errors

07

Reference

Credits

08

01

what is

What pug is

(and no, I don't mean the dog breed)

Is a high-performance template engine, implemented in JS for Node

What is made for

Substitute that 💩 of pure HTML and reuse the code

Yeah, reuse the code!

What to learn

Everything you will need for develop any app with Pug, from start to end

Tips and common errors included

let's get started!

02

Install

npm i --save-dev pug

Install with npm

Execute express

Import pug

import * as pug from "pug";

Define the view engine

app.set("view engine", "pug");
html
  head
    title!=title
  body
    h1!=message

create the hello world

Add express node

app.get('/', function (req, res) {
  res.render('index', { title: 'Hey', message: 'Hello there!'});
});

Yey, you have your pug working with express

Let's go learn the basics

03

the basics

what you need to know

with a basic knowledge of JS, you'll have the path made

about mixins

pug mixins are parts of code that can be used anywhere, with any content, many times you want

and you can insert data dinamically with express!

about inheritance

you have the main that can be extended as many times you and insert new data

with this idea, you can have a master template and multiple sub-templates that inherits from master

you're ready to go

Let's see real world examples to introduce you

04

examples

conditionals

- var logged = false

if logged
    p You're logged!
else
    p No, you're not...
- var user = 'Maria'

if user == 'Marta'
    p Marta user
else if user == 'María'
    p María user
else
    p You're not a platform user

you can do the same as you do with JS

For loops

In pug you will use each

ul
  each val in [1, 2, 3, 4, 5]
    li= val
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>
ul
  each val, index in {1:'one',2:'two',3:'three'}
    li= index + ': ' + val
<ul>
  <li>1: one</li>
  <li>2: two</li>
  <li>3: three</li>
</ul>

While loops

- var n = 0;
ul
  while n < 4
    li= n++
<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

Switch statement

- var friends = 10
case friends
  when 0
    p you have no friends
  when 1
    p you have a friend
  default
    p you have #{friends} friends
<p>you have 10 friends</p>

In pug you will use case

interpolation

- var riskyBusiness = "<em>Some of the girls are wearing my mother's clothing.</em>";
.quote
  p Joel: !{riskyBusiness}
<div class="quote">
  <p>Joel: <em>Some of the girls are wearing my mother's clothing.</em></p>
</div>

Useful for unescape text

Keep in mind that buffering unescaped content into your templates can be mighty risky if that content comes fresh from your users

attributes

Add in classes, href and more

input(
  type='checkbox'
  name='agreement'
  checked
)
<input type="checkbox" name="agreement" checked="checked" />
- var authenticated = true
body(class=authenticated ? 'authed' : 'anon')
<body class="authed"></body>

code

add code directly into pug

- for (var x = 0; x < 3; x++)
  li item
<li>item</li>
<li>item</li>
<li>item</li>
-
  var list = ["Uno", "Dos", "Tres",
          "Cuatro", "Cinco", "Seis"]
each item in list
  li= item
<li>Uno</li>
<li>Dos</li>
<li>Tres</li>
<li>Cuatro</li>
<li>Cinco</li>
<li>Seis</li>

id, class and divs

add classes, IDs and empty divs

div
    ul
        li Dog
        li Cat
<div>
    <ul>
        <li>Dog</li>
        <li>Cat</li>
    </ul>
</div>
.quote
    p This is my quote
<div class="quote">
    <p>This is my quote</p>
</div>
body#render
    #navbar
        p My navbar
<body id="render">
    <div id="navbar">
        <p>My navbar</p>
    </div>
</body>

Empty div

class

ID

mixins

code blocks created to make reusable code

mixin pet(name)
  li.pet= name

// Usage
ul
  +pet('cat')
  +pet('dog')
  +pet('pig')
<ul>
  <li class="pet">cat</li>
  <li class="pet">dog</li>
  <li class="pet">pig</li>
</ul>
mixin list
  ul
    li foo
    li bar
    li baz

//- Use
+list
+list
<ul>
  <li>foo</li>
  <li>bar</li>
  <li>baz</li>
</ul>
<ul>
  <li>foo</li>
  <li>bar</li>
  <li>baz</li>
</ul>

includes

include pug mixins or other things ( css, js ... )

//- index.pug
doctype html
html
  include includes/head.pug
  body
    h1 My Site
    p Welcome to my super lame site.
    include includes/foot.pug

//- includes/head.pug
head
  title My Site
  script(src='/javascripts/jquery.js')
  script(src='/javascripts/app.js')

//- includes/foot.pug
footer#footer
  p Copyright (c) foobar
<!DOCTYPE html>
<html>

<head>
  <title>My Site</title>
  <script src="/javascripts/jquery.js"></script>
  <script src="/javascripts/app.js"></script>
</head>

<body>
  <h1>My Site</h1>
  <p>Welcome to my super lame site.</p>
  <footer id="footer">
    <p>Copyright (c) foobar</p>
  </footer>
</body>

</html>

inheritance

add a basic template and extend

//- layout.pug
html
  head
    title My Site - #{title}
    block scripts
      script(src='/jquery.js')
  body
    block content
    block foot
      #footer
        p some footer content

//- page-a.pug
extends layout.pug

block content
  h1= title
  - var pets = ['cat', 'dog']
  each petName in pets
    include pet.pug
//- layout.pug
html
  head
    title My Site - #{title}
    block scripts
      script(src='/jquery.js')
  body
    block content
    block foot
      #footer
        p some footer content

//- sub-layout.pug
extends layout.pug

block content
  .sidebar
    block sidebar
      p nothing
  .primary
    block primary
      p nothing

aren't you still bored?

Jump to the tricks!

05

TRICKS

print json code

you can print JSON easily

- var json = {'time': 'now'}

p Hello, this is my JSON:
=JSON.stringify(json)

this will print the JSON as-is, avoiding the famous [object object]

maintain tags opened

open or close your tags with conditionals

- var url = false

if url
    | <a href='http://www.google.es'>

p you will see the url if the var is true

if url
    | </a>

useful if you want to print your tag only if the conditional is true

Remember that if you open a tag using this trick, you'll need to use the HTML tag instead of pug

add config to your mixins

pass config data to make your mixins customizables

mixin card_header(config)

    -
        var config = Object.assign({
            "title": config.title || ""
        }, config)

    if config.title
        .card-header
            .card-title!=config.title
.card
    +card_header({
        detail: config.detail || false,
        title: config.title
    })
    .card-body
        p my card!

print nested data 

print data from a nested source

-
    var user = {
        "name": "<strong>Pepito</strong>",
        "date": "20/02/2018",
        "today": "<em>No es hoy</em>"
    }

if user
    h1.hello
        | Bienvenido, 
        if user.name
            span.name!=user.name

    if user.date
        h2.date
            | Último login el #{user.date}
            if user.today
                | !{user.today}
<h1 class="hello">
    Bienvenido,
    <span class="name">
        <strong>Pepito</strong>
    </span>
</h1>
<h2 class="date">
    Último login el 20/02/2018 <em>No es hoy</em>
</h2>

dynamic mixin call

call your mixins dynamically

-
    var widgets = [
        {
            "name": "Hello"
        },
        {
            "name": "Goodbye"
        }
    ]

if widgets
    for widget in widgets
        +#{widget.name}
<p>Hello!</p>
<p>Goodbye!</p>
mixin hello
    p Hello!

mixin goodbye
    p Goodbye!

mixins

main.pug

forget parentheses

you don't need to use if your mixin don't include params

mixin dog
    p This is my dog

mixin animal(name)
    p This is my !{name}
<p>This is my dog</p>
<p>This is my cat</p>
+dog
+animal('cat')

mixins

main.pug

insert html tags

we can insert pure html if we want

if I want to put an anchor containing my card, I need to do a if/else... right?

we can do using whitespace control

06

errors

indent correctly

instead it will not work

Do

Don't

block content
  h1= title
  - var pets = ['cat', 'dog']
  each petName in pets
    include pet.pug
block content
  h1= title
  - var pets = ['cat', 'dog']
      each petName in pets
        include pet.pug

don't combine spaces with tabs, because it will warn you that it's not compatible

combine spaces

don't create two mixins with the same name, because it will don't know which one to use

don't duplicate

you cannot import dynamically mixins, this is impossible at the moment

dynamic imports

don't add ANY space after you insert hypen with a code block

remove spaces

instead it will not detect as JS code

07

reference

interpolation

- var text = 'hello'
- var texthtml = '<em>hello</em>'

// Put vars without equal
p Without html code: !{text}
p With html code: !{texthtml}

// Put vars with equal
p='Without html code: ' + text
p='With html code: ' + texthtml
p!='With html code: ' + texthtml
<p>Without html code:hello</p>
<p>With html code:<em>hello</em></p>

<p>Without html code:hello</p>
<p>With html code:<em>hello</em></p>
<p>With html code:&lt;em&gt;hello</p>

there are some rules you need to know

Use ! when you need to unescape any HTML code

more about interpolation

- var author = "enlore";
- var theGreat = "<span>escape!</span>";

p Written with love by #{author}
p This will be safe: #{theGreat}
<p>Written with love by enlore</p>
<p>This will be safe: &lt;span&gt;escape!&lt;/span&gt;</p>

more rules to be happy

Use ! when you need to unescape any HTML code

add js inside interpolation

- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}
<p>This is NOT MY INSIDE VOICE</p>

yes, you can

Use ! when you need to unescape any HTML code

and what about  }???

p No escaping for #{'}'}!
p No escaping for #{'<strong>b</strong>'}!
<p>No escaping for }!</p>
<p>No escaping for &lt;strong&gt;b&lt;/strong&gt;!</p>

of course, you can scape it

Use ! when you need to unescape any HTML code

p Escape for !{'<strong>b</strong>'}!
<p>Escape for <strong>b</strong>!</p>

whitespace control

p.
  Whitespace works #[strong correctly] and #[em we can] be happy.
<p>Whitespace works <strong>correctly</strong> and <em>we can</em> be happy.</p>

insert whitespace when you want

whitespace control 2

p
  | Use vertical bars for&nbsp;
  strong separate correctly
  | the non-strong text&nbsp;
  em em
  | from the em.
<p>Use vertical bars for <strong>separate correctly</strong> the non-strong text <em>em</em> from the em.</p>

same thing, different version

08

credits

thanks to the community of pug for doing that awesome job

and of course, thanks to google

i hope you liked it, found this useful and have learned something

Made with ❤️ by @matsumurae

Pug templates in a nutshell

By Amanda Copete

Pug templates in a nutshell

[Under construction] - Learn the basics about Pug ( also known as Jade ): tips and errors included.

  • 1,210