博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Express模版引擎hbs备忘
阅读量:6650 次
发布时间:2019-06-25

本文共 2745 字,大约阅读时间需要 9 分钟。

最近几天折腾了下express,想找个合适的模版引擎,下面是一些折腾过程的备忘

选择标准

选择一门模版语言时,可能会考虑的几点

  • 语法友好(micro tmpl那种语法真是够了)
  • 支持模版嵌套(子模版的概念)
  • 支持模版继承(extend)
  • 前后端共用
  • 有容错处理(最好定位到具体出错位置)
  • 支持预编译(性能好)

注意到hbs,似乎满足大部分的需求:

getting started

demo地址: 

目录结构如下:

.├── app.js├── node_modules│   ├── express│   └── hbs├── package.json└── views    └── index.hbs

看下app.js内容,还是比较容易理解的。模版views/index.hbs没什么好说的,语法跟handlbars一样

var express = require('express'),    hbs = require('hbs'),    app = express();app.set('view engine', 'hbs'); // 用hbs作为模版引擎 app.set('views', __dirname + '/views'); // 模版所在路径 app.get('/', function(req, res){ res.render('index', {title: 'hbs demo', author: 'chyingp'}); }); app.listen(3000);

模版继承:layout.hbs

demo地址:

如果稍微看过hbs源码可以知道,hbs默认会到views下找layout.hbs这个模版,将这个模板作为基本骨架,来渲染返回的页面。

getting-started里的例子来说,比如用户请求 ,那么,处理步骤如下

  1. 查找views/index.hbs,进行编译,并将编译的结果保存为 A
  2. 查找views/layout.hbs,如果 
    1. 存在:对layout.hbs进行编译,其中{
      {
      {body}}}
      标签替换成 A,并返回最终编译结果B
    2. 不存在:返回A

直接看例子。目录机构如下,可以看到多了个layout.hbs

.├── app.js├── node_modules│   ├── express│   └── hbs├── package.json├── public│   └── style.css└── views    ├── index.hbs    ├── layout.hbs └── profile.hbs

layout.hbs的内容如下:

 { { title}} 
{ { { body}}}

相应的,index.hbs调整为

Demo by {
{
author}}

{ { author}}: welcome to homepage, I'm handsome!

再次访问 ,可以看到返回的页面

模版继承+自定义扩展

demo地址:

在项目中,我们会有这样的需求。页面的基础骨架是共享的,但某些信息,每个页面可能是不同的,比如引用的css文件、meta标签等。那么,除了上面提到的“继承”之外,还需要引入类似“覆盖”的特性。

hbs官方其实就提供了demo ,感兴趣的同学可以去围观下。可以看到,在app.js里面加入了下面的 helper function`,这就是实现”覆盖“ 的关键代码了。

var blocks = {};hbs.registerHelper('extend', function(name, context) { var block = blocks[name]; if (!block) { block = blocks[name] = []; } block.push(context.fn(this)); // for older versions of handlebars, use block.push(context(this)); }); hbs.registerHelper('block', function(name) { var val = (blocks[name] || []).join('\n'); // clear the block blocks[name] = []; return val; });

此外,layout.hbs需要做点小改动。里面比较明显的变化是加入了下面的block标记

{
{
{block "stylesheets"}}}
{
{
{block "scripts"}}}

那么,可以在index.hbs里对这些标记的内容进行覆盖(或者说自定义),包括其他的模版,如果有需要,都可以对这两个`block进行覆盖。

{
{
#extend "stylesheets"}}
{ { /extend}} let the magic begin { { #extend "scripts"}} { { /extend}}

那么问题来了。如果有这样的需求:所有的页面,都引用 style.css,只有 index.hbs 引用 index.css,那么上面的改动还不足以满足这个需求。

其实,只需要改几行代码就可以实现了,扩展性点个赞。改动后的app.js如下

var blocks = {};hbs.registerHelper('extend', function(name, context) { var block = blocks[name]; if (!block) { block = blocks[name] = []; } block.push(context.fn(this)); // for older versions of handlebars, use block.push(context(this)); }); // 改动主要在这个方法 hbs.registerHelper('block', function(name, context) { var len = (blocks[name] || []).length; var val = (blocks[name] || []).join('\n'); // clear the block blocks[name] = []; return len ? val : context.fn(this); });

 

 
 

转载地址:http://gyito.baihongyu.com/

你可能感兴趣的文章
软件测试工程师必备技能,纯干货分享!
查看>>
文件类型
查看>>
NFS介绍、服务端安装配置、配置选项
查看>>
Dynamically changing $sp.getWidget options in Clie
查看>>
网页返回数据的逻辑梳理
查看>>
Linux中进程与线程的概念以及区别
查看>>
加粉啦 - 微信复制加粉统计,竞价加粉统计免费试用
查看>>
linux NAT 配置实现上网
查看>>
SQL语句优化技巧
查看>>
awk 简单认识
查看>>
dpkg: 另外一个进程已经为状态数据库加了锁
查看>>
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
查看>>
OSI模型
查看>>
网络营销外包
查看>>
小技巧:Percona5.5/5.6可以杀死空闲事务
查看>>
IT运维服务分类目录
查看>>
Jmeter对基于websocket协议的压力测试
查看>>
swarm+zookeeper配置docker集群
查看>>
国外一个牛人写好的VIM配置方案spf13
查看>>
Linux系统文件权限的备份与恢复
查看>>