在上周的内容里,小编介绍了如何在Node中使用类和常见的设计模式,今天小编和大家聊一聊NodeJS中的模板引擎。几乎所有的主流开发语言都为web开发而增加了模板支持,目的就是为了使模板与开发语言进行解耦。 


什么是模板到底什么是模板,首先我们先认识下什么不是模板,最直接的方式用一种语言生成另一种语言(用JavaScript 生成HTML):

.().().().()
也许你觉得这样写也没什么,如果有500行的HTML代码用这种方式,你还会用documen.write这样写嘛?小编认为一点意义也没。如果你写了大量的JavaScript,混合在HTML中会引起麻烦和混乱,到底会出现哪些麻烦呢?

  • 你必须不断地考虑哪些字符需要转移义及如何转义。
  • 使用多了,那些HTML很快会让你抓狂。
  • 很难发现不正确的HTML代码。
  • 很难直观的分析代码。
  • 很难让别人读懂你的代码。
  • 通常会失去编辑器语法高亮的特性。

但也有特例并不是一定不能在JavaScript中写HTML,只是你应该尽量避免这么做。尤其要感谢Jquery这样的类库,它让前端代码变得更优美。例如,这样的代码小编就觉得没问题:
$('#error').html('<h1>手机号已被人注册,请更换</h1>');
如果是这样:
().(+
    +
    +
    +
       )
小编在这就建议大家宁可使用模板,也不要使用JavaScript生成HTML,只有在某些简单的情况下才会使用JavaScript生成HTML。
如何选择模板引擎在NodeJS的世界里,有许多模板引擎可供选择,那么如何选择,确实是一个很头疼的问题,而如何选择模板取决于你产品的需求。下面是一些准则,仅供参考:性能显然大家都希望引擎模板尽可能的快!任何时候你都希望网站不会被拖慢。服务端、客户端能同时使用大多数,但不是所有模板引擎都可用于客户端和服务端。如果你需要在两端都是用模板,小编推荐大家选择两端都表现优秀的模板引擎。抽象你想让代码更有可读性或者私下里厌恶HTML已久,希望有什么东西能从尖括号里解脱出来?模板尤其服务端模板提供了一些解决方案。
这些只是些基本准则,如果你想了解关于这一主题更详细的说明,小编强烈推荐你看看Veena Basavaraj 的博客文章,那里有她为LinkedIn选择模板引擎时的相关规则。
LinkedIn 选择的是Dust,但是Handlebars也入围了,后者是小编要着重介绍的对象,Express 允许大家很方便切换任何一个模板引擎,如果你不喜欢Handlebars的话,你可以分分钟的换掉它。 
Jade :不走寻常路在大多数模板引擎还在以HTML为中心的时候,Jade就以抽象HTML细节而引入注目。如果你厌烦了HTML的语法标签,Jade模板就是一个很好的选择,下图代码摘自官方网站(http://jade-lang.com):  
Jade 无疑是少打了很多字,因为不再有尖括号和结束标记。尽管小编赞赏Jade理念和优雅的执行,但是小编发现,如果太过于抽象,作为一个前端开发者,HTML是核心,如果基本的尖括号从我们的习惯中抹掉,那种感受想必大家的感受和小编一样,还没有准备好接受Jade。如果你确定喜欢用抽象的Jade,网上还有很多资料可以帮助你。下面小编着重介绍下Handlbars。 
Handlebars基础Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板。它采用"Logic-less template"(无逻辑模版)的思路,在加载时被预编译,而不是到了客户端执行到代码时再去编译, 这样可以保证模板加载和运行的速度。Handlebars兼容Mustache,你可以在Handlebars中导入Mustache模板。
理解模板引擎的关键在于context(上下文环境)。当你渲染一个模板时,便会传递给模板引擎一个对象,叫作上下文对象,它能替换标识。

例如,如果上下文对象{name:’前端达人’},模板是 <p> 你好,{{name}}!</p>,则{{name}}会被前端达人替换掉。如果向模板中传递HTML文本会发生什么呢?例如,上下文换成 {name:’<b>前端达人</b>’},使用之前的模板得到的结果将是<p>hello,&lt;b&gt;前端达人&lt;b&gt;</p>,这或许并不是你想要的。要想解决这个问题,用三个大括号就可以了:{{{name}}}。如下图所示,我们可以看到Handlebars引擎是怎么使用上下文结合模板渲染HTML的:如何使用注释Handlebars的注释:{{! 在这里写注释}} 。懂得如何区分 Handlebars 注释和 HTML注释很重要,示例如下:{{! super-secret  注释}}<!-- HTML注释-->如果是服务端模板,上面写的super-secret 将不会被传到浏览器。看到这里你应该喜欢上Handlebars隐藏注释的特点。 
块级表达式当我们的模板显示需要有复杂的判断与显示逻辑,我们就需要考虑块级表达式,块级表达式提供了流程控制,条件执行和可扩展性。下面我们来一起看看上下文对象如何使用,首先我们创建一个上下文对象,如下示意代码:
= {
    : : {
        : : }: ::[
        {
            ::::[
                {
                    :::}{
                    :::}
            ]
        }{
            :::}
    ]
}
下面将上下文对象传递到模板中,相关代码如下:
    {{}}
    By {{.}}
    
        {{}}
    

Comments

    {{#}}
        {{/}}{{}}{{}}
        {{}}
        {{#}}
            {{#}}
            {{/}}{{}}{{}}
            {{}}
                {{/}}
            {{/}}
    {{/}}
这个模板稍微有些复杂,理解{{#each}}很重要,能循环遍历一个数组。如果要访问permalink对象,就得使用../来访问上一级上下文。{{if}}语句则进入了一个判断模块,类似js的if条件模块。

如何在Node中集成Handlebars在服务端使用Handlebars,会在HTML发送到客户端之前进行渲染。服务端模板和客户端模板不同,客户端模板用户可以通过右键查看源文件,而服务端模板用户将看不到,将会渲染完成以后发送到客户端。

服务端模板除了隐藏细节意外,还支持模板缓存,这对性能很重要。如果要显示的启用视图缓存,需要这样设置:


app.set(‘view cache’,true)。


让服务端支持Handlebars, 我们需要安装相关模块,通过以下方法进行安装:
nam install —save express3-handlebars
安装成功后,我们需要在Express中引用: 
=()
    .({:}).(.).()
在Express中使用(或不使用)布局在一个项目里,为了保证风格的统一性,大部分页面都采用的是相同的布局,所以我们编写一个默认的布局:
=()
    .({:})
默认情况下,Express会在view子目录总查找视图,在views/layouts 查找布局。所以如果有一个views/about.handlebars的视图,可以这样进行渲染,代码如下:
.get((reqres){
    res.()})

如果你不想使用布局,可以在上下文中指定layout:null:

.get((reqres){
    res.({:})})
或者你想使用一个不同的布局,可以指定布局名称:
.get((reqres){
    res.({:})})
局部文件想必大家都听说过组件吧,为了能在不同的页面进行重复的使用。我们可以使用Handlebars局部文件,比如我们有一个需求,想把评论模块做一个组件,我们可以这么做,首先创建一个views/partials/comment.handlebars:
    {{}}
    By {{.}}
    
        {{}}
    

Comments

    {{#}}
        {{/}}{{}}{{}}
        {{}}
        {{#}}
            {{#}}
            {{/}}{{}}{{}}
            {{}}
                {{/}}
            {{/}}
    {{/}}
然后我们在创建一个上下文对象渲染局部文件数据
= {
    : : {
        : : }: ::[
        {
            ::::[
                {
                    :::}{
                    :::}
            ]
        }{
            :::}
    ]
}(){
    }
现在创建一个中间件给 res.locals.partials 对象渲染局部文件数据,代码如下:
.((reqresnext){
    (!res..) res..={}res...=()next()})
现在我们就可以在其他模板中集成我们的局部文件了,编辑views/about.handlebars:
欢迎来到前端达人
{{> }}
语法{{> partial_name}} 可以让你在视图文件中包含一个局部文件。express3-handlebars 会在 views/partials中寻找一个partial_name.handlebars的视图。
段落段落(section)的概念最早出现在微软优秀的模板引擎Razor中。简单的说如果你需要在<head>元素中添加一些东西,或者在<script>标签里加入脚本,段落就派上用场了,现在小编就带着大家体验下,首先在App.js文件中实现如下代码: 
=()
    .({
        ::{
            :(nameoptions){
                (!.) .={}.[name]=options.()}
        }
})
然后我们在视图文件中使用段落的辅助方法,示意代码如下:
{{#}}

{{/}}


{{#}}
    
        (doucument).((){
                   ().()})
{{/}}
最后我们在布局文件里引用段落:


    
    
    {{{.}}}



{{{}}}
{{{.}}}
跟我一起学NodeJS,基础篇(五)_java关于handlebars的介绍就到这里,我们已经清楚了模板的易写、易读、易维护。我们不需要通过JavaScript拼接大量的HTML字符串了,我们可以使用一个小巧易读的模板使其动渲染。下周小编将会给大家详细介绍如何处理表单,敬请大家的期待。