Amanda Copete
Web developer lover of open source code.
Everything you need to start
What is
Install
The basics
Examples
Tricks
Errors
Reference
Credits
(and no, I don't mean the dog breed)
Yeah, reuse the code!
Tips and common errors included
npm i --save-dev pug
Import pug
import * as pug from "pug";
Define the view engine
app.set("view engine", "pug");
html
head
title!=title
body
h1!=message
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!'});
});
Let's go learn the basics
with a basic knowledge of JS, you'll have the path made
pug mixins are parts of code that can be used anywhere, with any content, many times you want
you have the main that can be extended as many times you and insert new data
Let's see real world examples to introduce you
- 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
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>
- var n = 0;
ul
while n < 4
li= n++
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
- 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
- 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
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>
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>
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
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>
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>
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
Jump to the tricks!
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]
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
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 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>
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
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
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
instead it will not work
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
don't create two mixins with the same name, because it will don't know which one to use
you cannot import dynamically mixins, this is impossible at the moment
don't add ANY space after you insert hypen with a code block
instead it will not detect as JS code
- 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:<em>hello</p>
there are some rules you need to know
Use ! when you need to unescape any HTML code
- 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: <span>escape!</span></p>
more rules to be happy
Use ! when you need to unescape any HTML code
- 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
p No escaping for #{'}'}!
p No escaping for #{'<strong>b</strong>'}!
<p>No escaping for }!</p>
<p>No escaping for <strong>b</strong>!</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>
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
p
| Use vertical bars for
strong separate correctly
| the non-strong text
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
Made with ❤️ by @matsumurae
By Amanda Copete
[Under construction] - Learn the basics about Pug ( also known as Jade ): tips and errors included.