Jade模板引擎入门教程

Wesley13
• 阅读 653

Jade是一款高性能简洁易懂的模板引擎,Jade是Haml的Javascript实现,在服务端(NodeJS)及客户端均有支持。 功能 客户端支持 超强的可读性 灵活易用的缩进 块扩展 代码默认经过编码处理以增强安全性 编译及运行时的上下文错误报告 命令行编译支持 HTML5模式(使用!!!5文档类型) 可选的内存缓存 联合动态和静态标记类 利用过滤器解析树的处理.

功能

Jade是一款高性能简洁易懂的模板引擎,Jade是Haml的Javascript实现,在服务端(NodeJS)及客户端均有支持。

功能

  • 客户端支持

  • 超强的可读性

  • 灵活易用的缩进

  • 块扩展

  • 代码默认经过编码处理以增强安全性

  • 编译及运行时的上下文错误报告

  • 命令行编译支持

  • HTML5模式(使用!!!5文档类型)

  • 可选的内存缓存

  • 联合动态和静态标记类

  • 利用过滤器解析树的处理

  • 支持 Express JS

  • 利用each透明的循环objects,arrays甚至不可枚举对象

  • 块注释

  • 不需要标记前缀

  • AST过滤器

  • 过滤器

    • :sass 需要安装 sass.js
    • :less 需要安装 less.js
    • :markdown 需要安装 markdown-js 或 node-discount
    • :cdata
    • :coffeescript 需要安装 coffee-script
  • Vim语法文件

  • TextMate包

  • Screencasts

其它语言实现

  • php
  • Scala
  • Ruby

安装

通过npm:

npm install jade

浏览器支持

可以通过下面命令将jade编译为客户端浏览器兼容的文件:

$ make jade.js

或者,如果你已经通过npm安装了uglifyjs(npminstalluglify-js),可以通过下面的命令同时创建两个文件:

$ make jade.min.js

公开API

var jade = require('jade'); // 渲染字符串 jade.render('.csser.com 字符串', { options: 'here' }); // 渲染文件 jade.renderFile('path/to/csser.com.jade', { options: 'here' }, function(err, html){ // 这里的options是可选的 // 回调函数可以作为第二个参数 }); // 编译一个函数 var fn = jade.compile('string of jade', options); fn.call(scope, locals);

Options

  • scope 执行作用域(this)
  • locals 本地变量对象
  • filename 处理异常及缓存时使用
  • cache 通过文件名将Javascript缓存在内存中
  • debug 输出生成的标记和函数体
  • compiler 替换jade默认编译引擎

语法

行尾

在解析前会将 CRLF 和 CR 转换为 LF.

标记

标记是一行的第一个单词:

html

会被转换为 

标记也可以有id:

div#container

这将被渲染成

如何处理类?

div.user-details

渲染为: 

多个class?并且还有id?

div#foo.bar.baz

渲染为:

总写div确实很烦人,可以省略之:

#foo .bar

输出: 

标记文本

只需要将文本内容放在标记后面:

p wahoo!

渲染为 

wahoo!

.

酷,但是如何处理大段文本呢?

p | foo bar baz | rawr rawr | super cool | go jade go

渲染为 

foo bar baz rawr.....

内插法?是的,这两种类型的文本都可以使用内插法,如果我们传入{ locals: { name: '一回', email: 'xianlihua[at]gmail.com' }},可以这样做:

#user #{name} <#{email}>

输出:

一回 <xianlihua[at]gmail.com>

出于某种原因需要输出#{}?转义之:

p \#{CSSer, 关注Javascript技术}

这样就得到了:

#{CSSer, 关注Javascript技术}

也可以使用反转义变量!{html},下面的代码将输出script标记:

- var html = "<script></script>" | !{html}

包含文本的嵌套标记也可以使用文本块:

label | Username: input(name='user[name]')

或者直接使用标记文本:

label Username: input(name='user[name]')

只接受纯文本的标记,如script,style,以及textarea不需要开头的|字符,例如:

 html
    head
      title CSSer, 关注Web前端技术 script if (foo) { bar(); } else { baz(); }

再次作为替代方案,我们可以使用点号'.'来表示一个文本块,例如:

 p. foo asdf
    asdf
     asdfasdfaf
     asdf
    asd.

输出:

 <p>foo asdf
    asdf
      asdfasdfaf
      asdf
    asd
    . </p>

如果点号'.'与标记之间有空格,Jade解析其会忽略它,将其作为文本处理:

p .

输出:

<p>.</p>

注释

单行注释当前看起来与Javascript一致,即“//”,单行注释的内容必须放在同一行上:

// 一些段落 p foo
p bar

将会输出:

<!-- 一些段落 --> <p>foo</p> <p>bar</p>

Jade也支持非缓冲注释,只需增加一个横杠:

//- 该行注释将不会被输出到解析后的页面中 p foo
p bar

输出:

<p>foo</p> <p>bar</p>

块注释

块注释会依据缩进进行处理:

 body // #content h1 CSSer,关注Web前端技术

输出:

<body> <!--
  <div id="content">
    <h1>CSSer,关注Web前端技术</h1>
  </div>
  --> </body>

Jade也支持条件注释,例如:

body /if IE
    a(href='http://www.mozilla.com/en-US/firefox/') Get Firefox

输出:

<body> <!--[if IE]>
    <a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a>
  <![endif]--> </body>

嵌套

Jade支持通过嵌套来以自然的方式定义标记:

ul
  li.first
    a(href='#') foo
  li
    a(href='#') bar
  li.last a(href='#') baz

块扩展

块扩展允许创建单行的简洁嵌套标记,下面的示例与上例输出相同:

 ul
    li.first: a(href='#') foo
    li: a(href='#') bar
    li.last: a(href='#') baz

特性

目前Jade支持'('和')'的特性定界符。

a(href='/login', title='View login page') Login

另外我们也可以使用冒号(:)来作为分割符:

a(href: '/login', title: '注册成为CSSer.com会员') Login

Boolean特性也被支持:

input(type="checkbox", checked)

值为变量的Boolean特性只有在值为true时输出:

input(type="checkbox", checked: someValue)

分拆在多行也能正常解析:

input(type='checkbox', name='agreement', checked)

文档类型

利用!!!来增加页面的文档类型:

!!!

将会输出过渡型文档类型,然而:

!!! 5

将会输出HTML5的文档类型,下面是默认定义的文档类型,这也可以很容易的被扩展:

var doctypes = exports.doctypes = { '5': '<!DOCTYPE html>', 'xml': '<?xml version="1.0" encoding="utf-8" ?>', 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">', 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">' };

要修改默认值只需改变:

jade.doctypes.default = 'whatever you want';

过滤器

过滤器以冒号(:)作为前缀,如 :markdown 将会对文本进行函数处理,(一回注:类似Smarty的变量调节器),本页开始处列出了目前Jade支持的过滤器。

body :markdown Woah! jade _and_ markdown, very **cool** we can even link to [CSSer](http://www.csser.com)

渲染后:

 <body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://www.csser.com">CSSer</a></p></body>

过滤器也可以处理解析树,通常过滤器可以正常处理文本块,但是通过传入规则的块过滤器可以做任何它能做的。

body
  conditionals: if role == 'admin' p You are amazing else p Not so amazing

代码

Jade目前支持三种类型的可执行代码,第一种以-为前缀,不会被缓冲:

- var foo = 'bar';

这可被用于条件或循环:

- for (var key in obj) p= obj[key]

由于Jade的缓冲技术,下面的代码是有效的:

- if (foo) ul
    li yay
    li foo
    li worked - else p oh no! you are not in csser.com

甚至详细的迭代循环:

- if (items.length) ul - items.forEach(function(item){ li= item - })

任何你希望的都可以实现!

接下来我们转义了缓冲代码,用于缓冲返回值,以等号(=)作为前缀:

- var foo = 'bar' = foo
h1= foo

输出: bar

bar

. 被'='缓冲的代码会默认经过转义以增强安全性,要输出为转义的值需要使用 !=:

p!= aVarContainingMoreHTML

一个允许使用"vanilla"Javascript的例外,是 - each 标记,其表现形式为:

- each VAL[, KEY] in OBJ

实现循环数组的例子:

- var items = ["one", "two", "three"] - each item in items
  li= item

输出:

<li>one</li> <li>two</li> <li>three</li>

循环对象的键和值:

- var obj = { foo: 'bar' } - each val, key in obj
  li #{key}: #{val}

这会输出 

  • foo: bar
  • 也可以进行嵌套循环:

    - each user in users - each role in user.roles
        li= role
    

    当一个属性为undefined,Jade会输出空串,例如:

    textarea= user.signature
    

    近期的Jade版本会输出空字符串而不是undefined:

    <textarea></textarea>
    

    命令行工具:bin/jade

    输出html到标准输出(stdout):

    jade examples/*.jade --pipe
    

    生成 examples/*.html :

    jade examples/*.jade
    

    传入参数:

    jade examples/layout.jade --options '{ locals: { title: "CSSer" }}'
    
    点赞
    收藏
    评论区
    推荐文章
    blmius blmius
    3年前
    MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
    文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
    Easter79 Easter79
    2年前
    swap空间的增减方法
    (1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
    待兔 待兔
    2个月前
    手写Java HashMap源码
    HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
    Wesley13 Wesley13
    2年前
    java中比较两个时间的差值
    项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
    Wesley13 Wesley13
    2年前
    Java获得今日零时零分零秒的时间(Date型)
    publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
    Wesley13 Wesley13
    2年前
    mysql设置时区
    mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
    Wesley13 Wesley13
    2年前
    00:Java简单了解
    浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
    Stella981 Stella981
    2年前
    Docker 部署SpringBoot项目不香吗?
      公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
    Wesley13 Wesley13
    2年前
    MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
    背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
    Python进阶者 Python进阶者
    8个月前
    Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
    大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这