Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端模板引擎学习 #28

Open
onvno opened this issue Jul 3, 2016 · 0 comments
Open

前端模板引擎学习 #28

onvno opened this issue Jul 3, 2016 · 0 comments

Comments

@onvno
Copy link
Contributor

onvno commented Jul 3, 2016

前端模板引擎学习

之前在练手node时,用过ejs模板,当时也对比过Jade,围观了一些前人在使用上的经验,众说纷纭.

有支持ejs,从语义上前端看着更舒服,如下。

<% if(!loginStatus) { %>
<div class="hero-unit">
    <h1>歡迎來到 Microblog</h1>
    <p>Microblog 是一個基於 Node.js 的微博系统。</p>
    <p>
        <a class="btn btn-primary btn-large" href="/login">登入</a>
        <a class="btn btn-large" href="/reg">立即註冊</a>
    </p>
</div>
<% } else { %>
<form method="post" action="/post" lass="well form-inline center" style="text-align:center;">
    <input type="text" class="span8" name="post">
    <button type="submit" class="btn btn-success"><i class="icon-comment icon-white"></i>發言</button>
</form>

而Jade的支持者,更是直言:**"肯定是Jade。EJS不要说跟Jade比,就是跟传统模板技术,比如Smarty比,也很挫了,比如不支持模板继承。"**Jade的语法结构,不如让我们看看:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) {
         bar(1 + 5)
      }
  body
    h1 Jade - node template engine
    #container.col
      if youAreUsingJade
        p You are amazing
      else
        p Get on it!
      p.
        Jade is a terse and simple
        templating language with a
        strong focus on performance
        and powerful features.

整体来说,即便如此,Jade的2个空格从心理上是接受不了的。现在问题来了,项目有需求:利用模板引擎完成页面内容的复用和嵌套,完成上线的静态页面优化。

那么该是创新的Jade,还是ejs,答案是:都不用。至少目前从需求来看,在部分功能不需求的情况下,前端模板引擎artTemplate能帮助完成。

在介绍之前,目前浅显的认为,模板引擎有以下明显优势:

  • 代码复用
  • 页面组件化

因为目前页面是静态化,所以以自己短浅的眼光看,用真正意义上的.html更能拉近前端和这个引擎世界的距离,毕竟.ejs,.jade都有种拒人千里之外的感觉。

试试artTemplate

官方第一种方法是通过页面加载template.js文件,自定义script type="text/html"来实现。demo如下

<head>
...
<script src="./template.js"></script>
</head>

<body>
<!--待插入的内容-->
<div id = "content"></div>

<!--编写模板-->
<script id="test" type="text/html">
<h1>{{title}}</h1>
<ul>
    {{each list as value i}}
        <li>索引 {{i + 1}} {{value}}</li>
    {{/each}}
</ul>
</script>

<!--渲染模板-->
<script>
var data = {
    title: '标签',
    list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
</script>
</body>

使用以上确实可实现渲染页面,特性和缺失如下:

  • 实现方式简单
  • 页面分离不够彻底美观
  • 页面渲染在前端执行,影响性能
  • 无法实现{{include}}

前边的一定程度上都可以忍受,但是无法实现{{include}}模板嵌套就没法忍了。

于是有了第二种方法:

针对artTemplate的预编译工具:TmodJS

TmodJS

tmodJS实现了{{include}}的功能,语法也基本与artTemplate一致,所以学习成本来说是极低的。

只需要安装tmodjs命令行工具:

npm install -g tmodjs

index.html页面实际如下:

{{include './header'}}

<div id="container">
    {{include './public/banner'}}

    <!-- 判断主体内容 -->
    {{if position == 'temppage'}}

    {{include './public/tempcont'}}

    {{/if}}

</div>

{{include './footer'}}

引用的公共区域以banner为例,内容如下,可以设置变量

<!-- banner开始 -->

<div class="banner">
    <div class="u-container">
        <div class="banner-content">
            <h1>{{title}}</h1>
            <p class="info">{{description}}</p>
        </div>
    </div>
</div>


<!-- banner结束 -->

通过运行

tmod

会默认将公共文件打包压缩为template.js,页面加载此文件,从而实现{{include}},然后其他执行如第一种方法。

从整体来看,除了实现引用{{include}},tmod依然没有解决我们后端直接输出html页面的需求。

好在我们还有第三种方法:

artTemplate的node版本

好了,支持

  • 支持预编译
  • 直接编译输出html页面
  • 命令简单

安装

npm install art-template

demo:

index.html

<html>
<head>
<meta charset='utf-8'>
<title>模板</title>
</head>

<body>
     <div id=”main”>
        {{include './common/header'}}
          <ul>
               {{each list}}
               <li>编号:{{$value.id}} &nbsp;&nbsp;姓名:{{$value.name}}</a></li>
               {{/each}}
          </ul>
     </div>
</body>
</html>

node中编译,将index.html输出为完整的静态页test.html

var fs = require('fs');
var template = require('art-template');
var datalist = require('./data.json'); // 引入数据

//渲染模板
var html = template('./index', datalist);
fs.writeFileSync('./test.html', html);

data.json内容

{"list": 
    [{"id":1, "name":"张三2"}, {"id":2, "name":"李四"}]
}

最终test.html输出结果

<html>
<head>
<meta charset='utf-8'>
<title>模板</title>
</head>
<body>
     <div id=”main”>
        <!-- 导航开始 -->
        ...
        <!-- 导航结束 -->
          <ul>

               <li>编号:1 &nbsp;&nbsp;姓名:张三2</a></li>

               <li>编号:2 &nbsp;&nbsp;姓名:李四</a></li>

          </ul>
     </div>
</body>
</html>

下边就是用node将整个文件复制编译出了,有时间再写。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant