Intro to Jade - A high performance template engine for JavaScript
When you build a JavaScript application, you'll almost certainly use some JavaScript templates. Rather than use a library like jQuery (or vanilla JavaScript) to update your HTML when values update, you can use templates, which cleans up your code hugely.
Obviously we don't just send text to the client, we usually send back HTML in standard web applications and deal with dynamic data in our applications as well.
Template engines offer us the ability to bind static HTML to dynamic data and output the result of the two as our HTML responses to serve our HTTP requests.
There are many template engines available:
"Template engines offer us the ability to bind static HTML to dynamic data and output the result of the two as our HTML responses to serve our HTTP requests."
All template engines have the same purpose of allowing us to pass data to our template engine to dynamically render static output
The main difference between them is more or less syntax of how we write our templates.
In Express, regardless of the template engine used the syntax to call them is the same using the res.render() function.
As noted before, the res object is the object we use to send an HTTP response back to the client based on the HTTP request our application received.
//When we call the render() function we pass it an object of data values to bind to output
app.get('/', function (req, res) {
res.render('index', { userName: 'Jason', email: 'jaywon@dark.net'});
});
Which would be passed to a template like:
//index.jade
h1
Hello #{username}
div
Your email is: #{email}
//index.hbs
<h1>
Hello {{username}}
</h1>
<div>
Your email is: {{email}}
</div>
Jade (.jade)
Handlebars (.hbs)
Both templates would render the exact same HTML output
To tell Express which template engine we will be using we need to:
$ npm install --save jade
//Tell Express which Template engine we are using by NPM module name
app.set('view engine', 'jade');
//Tell Express where our template files live
app.set('views', './views');
NOTE: Express will automatically append the file extension when using res.render() but needs to know where to look.
doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) {
bar(1 + 5)
}
body
h1 Jade - node template engine
#container.col
if youAreUsingJade
p You are amazing
else
p Get on it!
p.
Jade is a terse and simple
templating language with a
strong focus on performance
and powerful features.
Create elements by their tag name
h1
p
div
form
script
link
<h1></h1>
<p></p>
<div></div>
<form></form>
<script></script>
<link>
<input>
becomes...
This is how you add attributes
input(type="text" placeholder="insert text")
becomes...
<input type="text" placeholder="insert text">
Add classes with CSS-style syntax
div.container
ul#navigation
<div class="container"></div>
<ul id="navigation"></ul>
becomes...
section.small-12.medium-6.large-3#blue-background
<section id="blue-background" class="small-12 medium-6 large-3"></section>
becomes...
If you're just creating a div with classes and/or IDs, you can omit the `div` part of the code
.container
.small-12.medium-6.large-3.overlay
<div class="container"></div>
<div class="small-12 medium-6 large-3 overlay"></div>
becomes...
Using the keywords block and extends can help keep our templates dry
html
head
link(href="/path/to/client/side.js")
body
include ./includes/header.jade
block content
include ./includes/footer.jade
html
head
link(href="/path/to/client/side.js")
body
include ./includes/header.jade
block content
include ./includes/footer.jade
Allows you to inject Jade code. This is useful for code that needs to be reused
h1 Welcome to Fine Leather Goods LLC.
ul
li
a(href="/") Home
li
a(href="/about") About
li
a(href="/contact") Contact
li
a(href="/cart") Cart
layout.jade
./includes/header.jade
html
head
link(href="/path/to/client/side.js")
body
include ./includes/header.jade
block content
include ./includes/footer.jade
Once you have a layout defined you can extend it.
extends ./layout.jade
block content
h2 Fine Leather Goods
- var leatherGoods = ["Purse", "Wallets", "Shoes", "Luggage"]
ul
each goodie in leatherGoods
li= goodie
layout.jade
./index.jade
In your layout you must define a block.
Blocks must have a name is this cause it's content.
extends keyword takes a relative file path to your layout.
All the code in block content will be replace block content in layout.jade
to introduce (something additional or extraneous)
between other things or parts;
interject; interpose; intercalate.
- var leatherGoods = ["Purse", "Wallets", "Shoes", "Luggage"]
ul
each goodie in leatherGoods
li= goodie // this line isn't very helpful
- var leatherGoods = ["Purse", "Wallets", "Shoes", "Luggage"]
ul
each goodie in leatherGoods
li
a(href="/products/#{goodie}") Check out our amazing #{goodie}!
+goodieList(["Purse", "Wallets", "Shoes", "Luggage"])
Mixins allow you to create reusable blocks of jade.
+mixin goodieList(list)
ul
each goodie in list
li= goodie
Declaring a mixin
Using the mixin
Code used at compile time. The code above only works on the server-side. It will not make it over to the client. As you see, all it does it compile to simple HTML
- for (var x = 0; x < 3; x++)
li item
-
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>
<li>item</li>
<li>item</li>
<li>item</li>
Want basic Javascript in your jade?
- var user = { cart: ["Pappa's New Bag"] }
- var authorised = false
#user
if user.cart
h2 Items in your cart
ul
for item in user.cart
li= item
if authorised
h2 Buy Now
a.description(href="/checkout") checkout now!
else
h2 Create an account?
p.description.
you must be logged in to purchase!
Conditionals?