Node.js 使用jade模板引擎的示例


Posted in Javascript onMay 11, 2018

在“Node.js开发入门——Express安装与使用”里,我们曾经使用express generator创建了一个HelloExpress网站,express工具为我们生成了基本的目录结构、模板、stylesheet、routers等。虽然那只是一个简单的HelloWorld类的小东西,可里面包含的内容还是有些多了,为了更好的理解Express所支持的jade模板引擎的用法,我们这次提供一个手动创建的小网站,可以显示来访者的IP,并对访问进行计数。

安装jade

npm install -g jade

执行上面的命令,全局安装。

Visitor网站

第1步,在myprojects目录下创建一个Visitor目录。

第2步,把下面的代码保存在package.json文件里:

{
 "name": "Visitor",
 "version": "0.0.0",
 "private": true,
 "dependencies": {
 "express": "~4.13.1",
 "jade": "~1.11.0",
 }
}

这个json文件描述了我们的Visitor网站的一些信息,最重要的部分是依赖。我们要使用express和jade。

var express = require('express');
var app = express();

var counter = 0;

// view engine setup
app.set('views', './views');
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express);

app.get('/', function(req, res) {
 counter++;
 app.locals.counter = counter.toString();
 res.render('index', {ip: req.ip});
});

app.listen(3000);

app.locals.title = "Welcome to Visitor";
app.locals.counter = "0";

app.js文件是我们网站的入口。

第4步,创建一个views目录,在里面创建一个模板文件index.jade,内容如下:

doctype html
html
 head
 title= title
 body
 h1= title
 p Hello, #{ip}
 p You're the #{counter} visitor.

第5步,在Visitor目录里执行“npm install”,安装依赖。

第6步,在Visitor目录里执行“node app.js”,启动网站。

最后呢,就可以在浏览器里访问了,地址栏里输入“http://localhost:3000”即可,刷新几次,你可能会看到下面的界面:

Node.js 使用jade模板引擎的示例

这个简单的Visitor网站,和之前的HelloWorld、HelloExpress都不太一样了,它有了一些动态的内容。接下来我们就来看看这一切是如何发生的。

express与模板引擎

我在Visitor里使用了jade模板引擎,类似的还有ejs以及很多,可以访问这里来了解:https://github.com/joyent/node/wiki/Modules。

模板引擎使用模板文件来动态生成HTML文件,在生成时又可以按照一定的规则将应用程序里的数据整合进HTML文件。这样,我们既避免了手动编写HTML的繁琐(相对使用模板而言),又能生成具有动态内容的网页。

Express和Jade结合得比较好,我们来看看怎么配置它。

Express配置jade

Express服务器的行为可以通过一些设置选项来控制,这些选项可以通过express对象的set(setting, value)、enable(setting)和disable(setting)来设置。具体支持哪些设置,可以看这里http://expressjs.com/4x/api.html。我们的Visitor只用到了“view engine”和“views”。

“view engine”选项用来设置要使用的引擎,Visitor的代码如下:

app.set('view engine', 'jade');

“views”选项用来设置模板文件所在目录,Visitor的代码如下:

app.set('views', './views');

我在这里简单的使用了相对路径,更好的做法是使用path模块,根据全局变量__dirname来拼接。__dirname指当前正在执行的脚本所在的目录,对我们的Visitor示例来讲,就是app.js所在的那个目录。代码可能是这样的:

var path = require('path');
path.join(__dirname, 'views');

express默认会根据模板文件的扩展名来使用对应的引擎。对于*.jade文件,express内部会调用下面的语句:

app.engine('jade', require('jade').__express);

所以,我们的app.js,实际上也可以去掉这行代码,结果是一样的。

本地对象

我们可以在模板文件里包含动态数据,这些动态数据来自应用程序。我们可以使用express对象的locals对象来存储本地变量。下面的代码就存储了标题和访问计数:

app.locals.title = "Welcome to Visitor";
app.locals.counter = "0";

jade模板文件里可以直接访问express对象的locals对象的属性。我在app.js里设置的title和counter,在index.jade模板文件引用了它们。

现在我们来看这行代码:

res.render('index', {ip: req.ip});

它调用express的Response对象的render方法来渲染模板文件,并且传递了一个本地对象。render方法原型:

res.render(view [, locals] [, callback])

res.render方法渲染一个view并且把渲染生成的HTML字符串发送给客户端。res的API参考在这里http://expressjs.com/4x/api.html。

Response对象也有一个locals对象,它和app.locals的区别是,res的locals只在当前渲染的view内有效,而app.locals是全局的。

另外render方法的可选参数locals,也可以定义本地变量对象,传递给view。我在代码里把ip传了过去。

在jade文件里,常见的有两种方式可以调用由应用程序传入的本地变量:

  1. #{表达式}
  2. 标签=表达式

前面的index.jade模板文件里,对于页面标题,我们这么用的:

title= title

title是jade用来定义HTML文档title的标签。

对于body里的一级标题,我们这么用的(h1是jade用来定义HTML一级标题的标签):

h1= title

这都是属于“标签=表达式”这种调用方式,这种方式通常用在一行jade代码的开始,也就是标签开始的地方。而“#{表达式}”这种方式的好处是可以插入到jade模板文件的任意地方。比如:

p Hello, #{ip}
p You're the #{counter} visitor.

我们也可以将“h1= title”修改为“h1 #{title}”,效果一样。

jade引擎简介

jade使用一些标签来标记如何生成HTML,jade模板文件看起来很不像HTML文件,但它的模板文件小而整洁。使用jade,需要了解它都支持哪些标签,这个可以直接去看jade-lang,那里最详细也最权威,我们这里只介绍index.jade文件用到的那些标签。

关于jade,有两篇文章不错,可以看看,https://cnodejs.org/topic/5368adc5cf738dd6090060f2和https://3water.com/article/139936.htm,后面这篇文章是网友根号三写的一个关于jade的系列文章的开篇,整个系列里的文章都值得一看。

HTML文档的开始通常是文档声明,对应到jade模板文件里,就是doctype html。还有其它的文档类型,比如xml,可以写作doctype xml。更多请参考http://jade-lang.com/reference/doctype/。

jade有很多标签,用于生成HTML对应的标签。比如html对应,head对应,body对应,p对应,title对应,这也是我们的index.jade用到的所有标签了。通常我们在HTML里使用的标签写法,去掉尖括号就成了jade里可用的标签,比如对应jade里的div。

HTML标签往往可以设置name、id、class等属性,在jade里,是通过tag(attr=value)这种形式表示的。比如div(class=”view-container”),又比如input(type=”checkbox”)。

关于jade标签,这篇文章https://3water.com/article/139942.htm说得很好,请参考。

测试jade模板文件

一开始用jade模板,记不全它的标签,也经常不知道自己的写的模板文件生成的html文档是否正确。还好安装jade后,有一个命令行工具jade,可以用来验证模板文件。

jade的用法如下:jade [options] [dir|file …]

jade命令有很多选项,可以执行“jade -h”查看。要验证模板文件,最简单的办法就是使用jade工具生成为html文档。命令如下:

jade xxx.jade

执行上面的命令,就会在当前目录下生成一个与模板文件同名的html文档。不过格式很难读,完全是一坨屎挤在一起。加上 -P(?pretty) 就好了。这样:

jade -P xxx.jade

比如我们有这么一个使用了AngularJS的模板文件scope_template.jade,内容如下:

doctype html
html(ng-app="myApp")
 head
 title= title
 link(rel='stylesheet', href='/stylesheets/style.css')
 body
 div(ng-controller="SimpleTemplate")
 | ValueA: 
 input(type="number" ng-model="valueA")
 br
 | ValueB: 
 input(type="number" ng-model="valueB")
 br
 br
 | Expression Value: {{valueA + valueB}}
 br
 br
 input(type="button" ng-click="addValues(valueA, valueB)" value="Click to Add Values {{valueA}} & {{valueB}}")
 br
 | Clicked Value: {{valueC}}
 br

 script(src="/javascripts/angular-1.4.3.min.js")
 script(src="/javascripts/scope_template.js")

运行“jade -P scope_template.jade”命令会生成scope_template.html文件,内容如下:

<!DOCTYPE html>
<html ng-app="myApp">
 <head>
 <title></title>
 <link rel="stylesheet" href="/stylesheets/style.css" rel="external nofollow" >
 </head>
 <body>
 <div ng-controller="SimpleTemplate">ValueA: 
 <input type="number" ng-model="valueA"><br>ValueB: 
 <input type="number" ng-model="valueB"><br><br>Expression Value: {{valueA + valueB}}<br><br>
 <input type="button" ng-click="addValues(valueA, valueB)" value="Click to Add Values {{valueA}} & {{valueB}}"><br>Clicked Value: {{valueC}}<br>
 </div>
 <script src="/javascripts/angular-1.4.3.min.js"></script>
 <script src="/javascripts/scope_template.js"></script>
 </body>
</html>

需要提一下,我们既可以用jade编写完整的HTML文档,也可以编写符合HTML语法的局部模板。比如下面的jade文件:

div(class="admin-user")
 p 添加用户
 table
 tr
 td
 label 用户名:
 td
 input(type="text" name="add_username")
 tr
 td
 label 密码:
 td
 input(type="text" name="add_password") 
 tr
 td(colspan='2' align="right")
 input(type="submit" value="增加")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript折半查找详解
Jan 26 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
Aug 12 Javascript
js+ajax实现获取文件大小的方法
Dec 08 Javascript
jQuery简单操作cookie的插件实例
Jan 13 Javascript
Angular发布1.5正式版,专注于向Angular 2的过渡
Feb 18 Javascript
js实现上传图片及时预览
May 07 Javascript
javascript表单事件处理方法详解
May 15 Javascript
使用vue.js制作分页组件
Jun 27 Javascript
原生js仿jquery一些常用方法(必看篇)
Sep 20 Javascript
原生js实现选项卡功能
Mar 08 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
Mar 15 Javascript
Angular2使用vscode断点调试ts文件的方法
Dec 13 Javascript
Node.js Express安装与使用教程
May 11 #Javascript
Node.js创建HTTP文件服务器的使用示例
May 11 #Javascript
Node.js引入UIBootstrap的方法示例
May 11 #Javascript
Node.js使用Angular简单示例
May 11 #Javascript
Node.js 使用AngularJS的方法示例
May 11 #Javascript
Angular使用动态加载组件方法实现Dialog的示例
May 11 #Javascript
详解JavaScript中的数组合并方法和对象合并方法
May 11 #Javascript
You might like
PHP模板引擎SMARTY
2006/10/09 PHP
安装apache2.2.22配置php5.4(具体操作步骤)
2013/06/26 PHP
WordPress中用于检索模版的相关PHP函数使用解析
2015/12/15 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
2016/09/19 PHP
js获取字符串最后一位方法汇总
2014/11/13 Javascript
node.js中的fs.symlinkSync方法使用说明
2014/12/15 Javascript
Vue.js每天必学之组件与组件间的通信
2016/09/08 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
Vue 2.0 服务端渲染入门介绍
2017/03/29 Javascript
JavaScript基于面向对象实现的猜拳游戏
2018/01/03 Javascript
jQuery实现带3D切割效果的轮播图功能示例【附源码下载】
2019/04/04 jQuery
百度小程序自定义通用toast组件
2019/07/17 Javascript
JS正则表达式验证密码强度
2020/03/18 Javascript
基于javascript canvas实现五子棋游戏
2020/07/08 Javascript
[03:51]吞吞映像 每周精彩击杀top10第二弹
2014/06/25 DOTA
Python中的字符串类型基本知识学习教程
2016/02/04 Python
Python实现读取邮箱中的邮件功能示例【含文本及附件】
2017/08/05 Python
分析Python中解析构建数据知识
2018/01/20 Python
Python实现按逗号分隔列表的方法
2018/10/23 Python
python 列表递归求和、计数、求最大元素的实例
2018/11/28 Python
python 元组的使用方法
2020/06/09 Python
使用python把xmind转换成excel测试用例的实现代码
2020/10/12 Python
Python批量删除mysql中千万级大量数据的脚本分享
2020/12/03 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
你的自行车健身专家:FaFit24
2016/11/16 全球购物
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
澳大利亚最大的在线美发和美容零售商之一:My Hair Care & Beauty
2019/08/24 全球购物
家长会主持词开场白
2014/03/18 职场文书
王老吉广告词
2014/03/20 职场文书
团日活动总结书
2014/05/08 职场文书
经理岗位职责范本
2015/04/15 职场文书
《百分数的认识》教学反思
2016/02/19 职场文书
看古人们是如何赞美老师的?
2019/07/08 职场文书
62句有关感恩节文案(推荐收藏)
2019/11/28 职场文书
实体类或对象序列化时,忽略为空属性的操作
2021/06/30 Java/Android
Mysql数据库手动及定时备份步骤
2021/11/07 MySQL