Node.js开发入门—使用jade模板引擎

“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。

第3步,把下面的代码保存到app.js文件里:

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”即可,刷新几次,你可能会看到下面的界面:

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

express与模板引擎

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

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

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

Express配置jade

Express服务器的行为可以通过一些设置选项来控制,这些选项可以通过express对象的set(setting, value)、enable(setting)和disable(setting)来设置。具体支持哪些设置,可以看这里http://expressjs.com/4x/api.html#app.settings.table。我们的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#res

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/5368adc5cf738dd6090060f2http://www.html-js.com/article/2570,后面这篇文章是网友根号三写的一个关于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标签,这篇文章http://www.html-js.com/article/2575说得很好,请参考。还有这篇http://iammr.7.blog.163.com/blog/static/49102699201391625916658/,也不错。

测试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">
  </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}} &amp; {{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="增加")


其它文章:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 19:10:48

Node.js开发入门—使用jade模板引擎的相关文章

Node.js开发入门—语音合成示例

出于项目需要,搞了一个语音合成(TTS)的小示例,使用的是OKVoice. 我想在PC上测试,OKVoice的快速接入API可以实现我的目的,文档在这里:http://dev.okvoice.com/file.php. 直接上代码吧,okVoiceTts.js,内容如下: var http = require('http'); var fs =require('fs'); var crypto = require('crypto'); var util = require('util'); va

Node.js开发入门—使用对话框ngDialog

做网站经常会遇到弹出对话框获取用户输入或弹出对话框让用户确认某个操作之类的情景,有一个基于AngularJS的扩展模块可以帮我们优雅地完成这类事情:ngDialog. ngDialog在github上提供了一个示例网页,演示了它的各种用法,在这里:https://github.com/likeastore/ngDialog/blob/master/example/index.html.ngDialog的github主页的readme也对常用的指令和服务做了较为详细的介绍,可以参考.我这篇就纯粹是

Node.js开发入门—Stream用法详解

Stream是Node.js中非常重要的一个模块,应用广泛.一个流是一个具备了可读.可写或既可读又可写能力的接口,通过这些接口,我们可以和磁盘文件.套接字.HTTP请求来交互,实现数据从一个地方流动到另一个地方的功能. 所有的流都实现了EventEmitter的接口,具备事件能力,通过发射事件来反馈流的状态.比如有错误发生时会发射"error"事件,有数据可被读取时发射"data"事件.这样我们就可以注册监听器来处理某个事件,达到我们的目的. Node.js定义了R

Node.js开发入门—Angular简单示例

在"使用AngularJS"中,我们提到了如何在Node.js项目中引入AngularJS,这次提供一个非常简单的示例,演示AngularJS里的指令.数据绑定.服务等内容. 我准备做Web后台管理系统,不同的管理员会有不同的权限,管理员登录后看到的菜单和他的权限有关,能看到什么,是动态生成的(类似RBAC).本文的示例从这个项目而来,当然,现在还是最简单的. 如果没有特别说明,后面我们用到的示例都使用express generator生成. Angular小demo 先搞起来吧. 第

Node.js开发入门—UDP编程

Node.js也提供了UDP编程的能力,相关类库在"dgram"模块里. 与TCP不同,UDP是无连接的,不保障数据的可靠性,不过它的编程更为简单,有时候我们也需要它.比如做APP的统计或者日志或者流媒体,很多流媒体协议都会用到UDP,网上一搜一大堆. 使用UDP,如果你要发送数据,只需要知道对方的主机名(地址)和端口号,扔一消息过去即可.至于对方收不收得到,听天由命了.这就是数据报服务,类似快递或邮件. 我们这次来介绍一下Node.js里的UDP编程,我会提供一个UDP版本的echo

Node.js开发入门—使用http访问外部世界

Node.js的http模块,不但可以构建服务器,也可以作为客户端类库来访问别的服务器.关键就在两个方法: http.request(options[,callback]) http.get(path[,callback]) 除了http,还会用到FileSystem模块和Stream中的stream.Readable和stream.Writable. 先来大概介绍一下相关API吧. API解释 http.request()方法接受一个options参数,这个参数可以是对象,用来指明你要访问的网

Node.js开发入门—套接字(socket)编程

Node.js的net模块提供了socket编程接口,方便我们利用较为底层的套接字接口来实现应用协议.这次我们看一个简单的回显服务器示例,包括服务端和客户端的代码. 使用JavaScript也可以进行套接字编程,哈哈,这酸爽! 代码 分服务器和客户端两部分来说吧. echoServer代码分析 echoServer.js: var net = require("net"); // server is an instance of net.Server // sock is an ins

Node.js开发入门—notepad++ for Node.js

对于Node.js开发,论IDE的话,Webstorm是不二的选择,但它是收费的(可免费使用30天).一开始,我们先将就一下,使用notepad++来编写Node.js应用.这样做还有一大好处:没有关于Node.js的代码高亮和自动补全,可以更好地敦促我们使用在线API文档记忆各种类库API.死磕自己吧,enjoy it. notepad++的安装与配置 到"https://notepad-plus-plus.org/download/v6.8.2.html"这里下载吧,6.8.2版本

Node.js开发入门—使用AngularJS内置服务

在上一篇,"AngularJS简单示例"中演示了一个非常简单的使用Angular的小demo,那篇已经太长,原本要介绍的一些内容只好单另开篇了.这些内容,就是如何使用Angular服务. 我们还是基于"AngularJS简单示例"中的示例来改造一下.新的示例,能从Node.js+Express构造的服务器上获取管理菜单.为了实现这个,需要做几部分改造: 服务器提供adminMenu的下载功能,需要修改app.js,处理路由 修改Angular实现的控制器x-cont