第4章-模板引擎Jade和Handlebars-4.2.Jade的语法和特性

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.js</h1>
        <p>The only book most people will ever need.</p>
    </div>
    <div>
        <footer>&copy; Apress</footer>
    </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 Guide</h1>
<p>The Comprehensive Book on Express.js</p>

三、属性

属性紧跟在标签的名字之后,用括号括起来,格式是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 Guide</a>
    <form action="/login">
        <button type="submit" value="保存"></button>
    </form>
    <div class="hero-unit">Learn Node.js</div>
</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)

<input type="radio" checked="checked" />
<input type="radio" checked="checked" />
<input 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 us</a>
        </span>
    </p>
</div>

注意:如果没有写标签名,则默认就是div标签

五、文本

通过符号|可以输出原始文本

六、Script和Style块

有时,开发人员要在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代码

与上面例子相反,如果要在模板编译时使用JavaScript代码,
即,要在Jade中写可以操作输出的可以执行JavaScript代码,可以使用符号-、=或!=。
这在要输出HTML元素和注入JavaScript时是很有用的,很显然,处理这种操作要小心,要避免跨站脚本(XSS)攻击,
如:

- var arr= ['<a>','<b>','<c>']
ul
    - for(var i=0; i<arr.length; i++)
        li
            span=i
            span!="unescaped: " + arr[i] + "vs."
            span= "escaped: " + arr[i]

会生成这个:

<ul>
    <li><span>0</span><span>unescaped: <a> vs. </span><span>escaped: &lt;a&gt;</span></li>
    <li><span>1</span><span>unescaped: <b> vs. </span><span>escaped: &lt;b&gt;</span></li>
    <li><span>2</span><span>unescaped: <c> vs. </span><span>escaped: &lt;c&gt;</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 深情小建

输出:

<!-- content goes here-->
<p> Node.js is a non-blocking I/O for scalable apps.</p>
<p id="footer">Copyright 2015 深情小建</p>

九、if语句

给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,他相当于不或者!

十、each语句

与if语句相似,Jade里的迭代可以只简单地写each,
如:

- var languages = ['php', 'node', 'java', 'ruby', 'c++']
div
    each value, index in languages
        p= index + ". " + value

输出的HTML如下

<div>
    <p>0. php</p>
    <p>1. node</p>
    <p>2. java</p>
    <p>3. ruby</p>
    <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: -1</p>
    <p>node: 2</p>
    <p>java: 3</p>
    <p>ruby: 6</p>
    <p>c++: 1</p>
</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(-)里使用它。

十三、case

- 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

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是一种自顶向下的方法,
格式:include /path/filename。
如:include ./includes/header
注:不用给模板名字和路径加双引号或单引号
下面的例子会从父目录开始查找:
include ../includes/footer
但是,没有办法在文件名和文件路径里使用变量,因为includes/partials是在编译时处理的,而不是在执行时。

十六、extend

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值