Jade是Node.js的一个模板引擎,他借鉴了Haml,语法和Haml相似,支持空格缩进。
一行开头的任何文件都会被默认解释成HTML标签,Jade的主要优势是为HTML元素同时渲染闭合和开始标签,
标签后的文本和空格会被解释成内联HTML,也就是元素的文本内容。如:
Body
div
h1 Practical Node.js
p The only book most people will ever need.
div
footer © Apress
上面的模板会输出:
<body>
<div>
<h1>Practical Node.jsh1>
<p>The only book most people will ever need.p>
div>
<div>
<footer>© Apressfooter>
div>
body>
传给Jade模板的数据称为locals。要输出一个变量的值,使用等号=。
Jade代码:
h1= title
p= body
(locals):
{
title: "Express.js Guide",
body: "The Comprehensive Book on Express.js"
}
输出的HTML:
<h1>Express.js Guideh1>
<p>The Comprehensive Book on Express.jsp>
属性紧跟在标签的名字之后,用括号括起来,格式是name=value。多个属性之间用逗号分割。
如:
div(id="content", class="main")
a(href="http://expressjsguide.com", title="Express.js Guide", target="_blank") Express.js Guide
form(action="/login")
button(type="submit", value="保存")
div(class="hero-unit") Lean Node.js!
会变成:
<div id="content" class="main">
<a href="http://expressjsguide.com" title="Express.js Guide" target="_blank">Express.js Guidea>
<form action="/login">
<button type="submit" value="保存">button>
form>
<div class="hero-unit">Learn Node.jsdiv>
div>
有时,一个属性的值必须是动态的,在这种情况下,只需要使用该变量的名字。符号|允许我们在新的一行里写HTML节点的内容,换句话说,就是有符号|的那行会变成文本内容。
如:
a(href=url, data-active=isActive)
label
input(type="checkbox", checked=isChecked)
| yes / no
给上面的模板提供数据:
{
url: "/logout",
isActive: true,
isChecked: false
}
模板和数据一起会输出如下:
<a href="/logout" data-active="data-active">a>
<label>
<input type="checkbox" />yes / no
label>
注意:值是false的属性在输出HTML代码时会被忽略;而当没有传值时,会被赋值为true
如:
input(type="radio", checked)
input(type="radio", checked=true)
input(type="radio", checked=false)
type="radio" checked="checked" />
type="radio" checked="checked" />
type="radio" />
为了方便起见,可以直接在标签名之后写类和ID。比如,我们给一个段落使用类lead和center,给一个div使用ID side-bar和类pull-right(再次使用符号|创建文本内容):
div#content
p.lead.center
| webapplog: where code lives
#side-bar.pull-right
span.contact.span4
a(href="/contact">Contact us
翻译成:
<div id="content">
<p class="lead center">
webapplog: where code lives
<div id="side-bar" class="pull-right">div>
<span class="contact span4">
<a href="/contact">Contact usa>
span>
p>
div>
注意:如果没有写标签名,则默认就是div标签
通过符号|可以输出原始文本
有时,开发人员要在HTML的script 或 style标签里写内容块。这时,可以使用点号. 比如,可以这样写前端JavaScript:
script.
console.log('Hello Jade!')
setTimeout(function(){
window.location.href='http://rpjs.co'
}, 200)
console.log('Good bye!')
翻译成:
<script>
console.log('Hello Jade!')
setTimeout(function(){
window.location.href='http://rpjs.co'
}, 200)
console.log('Good bye!')
script>
与上面例子相反,如果要在模板编译时使用JavaScript代码,
即,要在Jade中写可以操作输出的可以执行JavaScript代码,可以使用符号-、=或!=。
这在要输出HTML元素和注入JavaScript时是很有用的,很显然,处理这种操作要小心,要避免跨站脚本(XSS)攻击,
如:
- var arr= ['','','' ]
ul
- for(var i=0; i"unescaped: " + arr[i] + "vs."
span= "escaped: " + arr[i]
会生成这个:
<ul>
<li><span>0span><span>unescaped: <a> vs. span><span>escaped: <a>span>li>
<li><span>1span><span>unescaped: <b> vs. span><span>escaped: <b>span>li>
<li><span>2span><span>unescaped: <c> vs. span><span>escaped: <c>span>li>
ul>
提示:Jade和Handlebars的一个主要区别是:Jade允许在代码里写几乎所有的JavaScript;
而Handlebars则限制开发人员只能使用少量的内置和自定义的helpers。
想输出注释:用JavaScript的注释形式//
不想输出注释:则使用//-
如:
// content goes here
p Node.js is a non-blocking I/O for scalable apps.
//- @todo change this to a class
p(id="footer") Copyright 2015 深情小建
输出:
<p> Node.js is a non-blocking I/O for scalable apps.p>
<p id="footer">Copyright 2015 深情小建p>
给if语句加个前缀-,就可以写标准的JavaScript代码了。
也可以使用一种极简的不需要前缀、不需要括号的替代写法
如:
- var user = {}
- user.admin = Math.random() > 0.5
if user.admin
button(class="launch") Launch Spacecraft
else
button(class="login") Log in
除了if外,还有unless,他相当于不或者!
与if语句相似,Jade里的迭代可以只简单地写each,
如:
- var languages = ['php', 'node', 'java', 'ruby', 'c++']
div
each value, index in languages
p= index + ". " + value
输出的HTML如下
<div>
<p>0. phpp>
<p>1. nodep>
<p>2. javap>
<p>3. rubyp>
<p>4. c++p>
div>
同样的写法也适用于是对象的时候:
- var languages = {'php': -1, 'node': 2, 'java': 3, 'ruby': 6, 'c++': 1}
div
each value, key in languages
p= key + ": " + value
上面的Jade被编译后,输出HTML
<div>
<p>php: -1p>
<p>node: 2p>
<p>java: 3p>
<p>ruby: 6p>
<p>c++: 1p>
div>
当有一个文本块需要用另外一种语言写时,就会用到过滤器。比如:Markdown的过滤器的写法如下:
p
:markdown
# Practical Node.js
[This book](http://expressjsguide.com) really helps to grasp many components needed for modern-day web development.
注意:要想使用Markdown的过滤器,需要安装Markdown模块,以及marked和Markdown NPM包。不需要其他配置,只要在项目的本地文件夹node_modules下安装他们即可。
Jade中读取变量的值是通过#{name}来实现的。
如:
- var title = "Express.js Guide"
p Read the #{title} in PDF, MOBI and EPUB
在模板编译时变量的值就会被处理,因此,不要在可执行JavaScript(-)里使用它。
- var coins = Math.round(Math.random() * 10)
case coins
when 0
p You have no money
when 1
p You have a coin
default
p You have #{coins} coins!
mixin是带参数,并产生一些HTML的函数。声明的语法是mixin name(param, param2, …),用法是+name(data)
如:
mixin row(items)
tr
each item, index in items
td= item
mixin table(tableData)
table
each row, index in tableData
+row(row)
- var node = [{name: "深情小建"}, {name: "刘德华"},{name: "孙悟空"}]
+table(node)
- var js= [{name: "那英"}, {name: "哈林"},{name: "王峰"}]
+table(js)
上面的模板和数据生成的HTML代码如下:
<table>
<tr>
<td>深情小建td>
tr>
<tr>
<td>刘德华td>
tr>
<tr>
<td>孙悟空td>
tr>
table>
<table>
<tr>
<td>那英td>
tr>
<tr>
<td>哈林td>
tr>
<tr>
<td>王峰td>
tr>
table>
include是把逻辑提取到单独文件里的一种方式,旨在让多个文件重用他,
include是一种自顶向下的方法,
格式:include /path/filename。
如:include ./includes/header
注:不用给模板名字和路径加双引号或单引号
下面的例子会从父目录开始查找:
include ../includes/footer
但是,没有办法在文件名和文件路径里使用变量,因为includes/partials是在编译时处理的,而不是在执行时。
extend是一种自底向上的方法(和include相反)
格式:extend filename 和 block blockname
如:
在文件file_a里:
block header
p some default text
block content
p Loading ...
block footer
p copyright
在文件file_b里:
extend file_a
block header
p very specific text
block content
.main-content