Express模版引擎hbs备忘
最近几天折腾了下express,想找个合适的模版引擎,下面是一些折腾过程的备忘
选择标准
选择一门模版语言时,可能会考虑的几点
- 语法友好(micro tmpl那种语法真是够了)
- 支持模版嵌套(子模版的概念)
- 支持模版继承(extend)
- 前后端共用
- 有容错处理(最好定位到具体出错位置)
- 支持预编译(性能好)
注意到hbs,似乎满足大部分的需求:https://github.com/donpark/hbs
getting started
demo地址:https://github.com/chyingp/blog/tree/master/demo/2015.04.01-hbs/getting-started
目录结构如下:
.
├── 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地址:https://github.com/chyingp/blog/tree/master/demo/2015.04.01-hbs/inherit-from-layout
如果稍微看过hbs
源码可以知道,hbs默认会到views
下找layout.hbs
这个模版,将这个模板作为基本骨架,来渲染返回的页面。
以getting-started
里的例子来说,比如用户请求 http://127.0.0.1:3000,那么,处理步骤如下
- 查找
views/index.hbs
,进行编译,并将编译的结果保存为 A - 查找
views/layout.hbs
,如果- 存在:对
layout.hbs
进行编译,其中{{{body}}}
标签替换成 A,并返回最终编译结果B - 不存在:返回A
- 存在:对
直接看例子。目录机构如下,可以看到多了个layout.hbs
。
.
├── app.js
├── node_modules
│ ├── express
│ └── hbs
├── package.json
├── public
│ └── style.css
└── views
├── index.hbs
├── layout.hbs
└── profile.hbs
layout.hbs
的内容如下:
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
{{{body}}}
</body>
</html>
相应的,index.hbs
调整为
<h1>Demo by {{author}}</h1>
<p>{{author}}: welcome to homepage, I'm handsome!</p>
再次访问 http://127.0.0.1:3000,可以看到返回的页面
模版继承+自定义扩展
demo地址:https://github.com/chyingp/blog/tree/master/demo/2015.04.01-hbs/inherit-and-override
在项目中,我们会有这样的需求。页面的基础骨架是共享的,但某些信息,每个页面可能是不同的,比如引用的css文件、meta标签等。那么,除了上面提到的“继承”之外,还需要引入类似“覆盖”的特性。
hbs官方其实就提供了demohttps://github.com/donpark/hbs/blob/master/examples/extend/ ,感兴趣的同学可以去围观下。可以看到,在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"}}
<link rel="stylesheet" href="/css/index.css"/>
{{/extend}}
let the magic begin
{{#extend "scripts"}}
<script>
document.write('foo bar!');
</script>
{{/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);
});
Express模版引擎hbs备忘的更多相关文章
- Express学习 ------模版引擎(handlebars)
Handlebars一款js模版引擎,我们在做客户端开发的时候,也可能已经使用过.它语法比较简单,和我们平常写的html 一样,只不过html 中可以加入handlebars 表达式. handleb ...
- Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs
目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use ...
- Express安装入门与模版引擎ejs
Express安装入门与模版引擎ejs 目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set ...
- Nodejs学习笔记(五)—Express安装入门与模版引擎ejs
前言 前面也学习了一些Node.js的基本入门知道,现在开始进入Web开发的部分: Node.js提供了http模块,这个模块中提供了一些底层接口,可以直接使用,但是直接开发网站那还是太累了,所以ht ...
- 【11】 Express安装入门与模版引擎ejs
前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use([p ...
- AngularJS之备忘与诀窍
译自:<angularjs> 备忘与诀窍 目前为止,之前的章节已经覆盖了Angular所有功能结构中的大多数,包括指令,服务,控制器,资源以及其它内容.但是我们知道有时候仅仅阅读是不够的. ...
- 简单JavaScript模版引擎优化
在上篇博客最简单的JavaScript模板引擎 说了一下一个最简单的JavaScript模版引擎的原理与实现,作出了一个简陋的版本,今天优化一下,使之能够胜任日常拼接html工作,先把上次写的模版函数 ...
- Nmap备忘单:从探索到漏洞利用(Part 5)
这是备忘单的最后一部分,在这里主要讲述漏洞评估和渗透测试. 数据库审计 列出数据库名称 nmap -sV --script=mysql-databases 192.168.195.130 上图并没有显 ...
- Nmap备忘单:从探索到漏洞利用(Part 4)
这是我们的Nmap备忘单的第四部分(Part 1. Part 2. Part 3).本文中我们将讨论更多东西关于扫描防火墙,IDS / IPS 逃逸,Web服务器渗透测试等.在此之前,我们应该了解一下 ...
随机推荐
- 将sqllite3数据库迁移到mysql
一.安装python mysql module (OneDrive): 1.运行python D:\OneDrive\Work\django\mysqlregistry.py2.http://www. ...
- orcle 如何快速插入百万千万条数据
有时候做实验测试数据用到大量数据时可以用以下方法插入: 方法一:使用xmltable create table bqh8 as select rownum as id from xmltable('1 ...
- 7zip批量压缩,并批量改.jar
批量压缩.bat--要和将要压缩的文件在同一级目录下 for /d %%X in (*) do "D:\Program Files\7-Zip\7z.exe" a "%% ...
- fedora安装字体
#fedora安装新字体 将自己现有的字体复制到/usr/share/fonts/自己起个名字/ 例如我要安装下载的苹果苹方字体 #cp 我这个文件夹的地址/* /usr/share/fonts/Pi ...
- elasticsearch安装步骤
今天我们来安装一下elasticsearch,我们采用RPM包安装的方式来,版本为6.5.4.系统为centos7.5版本. 1.首先设置系统环境 1)编辑/etc/sysctl.conf文件添加下面 ...
- 1.1环境的准备(一)之Python解释器的安装
目录: 1.Python-解释器的下载 2.Python-解释器的安装 3.Python-解释器的测试 4.Python的环境变量的配置 (一)Python解释器的安装: 1.官网:https://w ...
- Lombok快速上手(安装、使用与注解参数)
目录 Lombok插件安装与使用说明 常见参数 lombok的依赖于安装 依赖管理 IDEA插件的安装 @Data小例子 扩展@ToString 构造器注解扩展 @Log及其他日志注解 资料链接 Lo ...
- bootstrap模态框input不能获取焦点并编辑【转】
Bootstrap模态框时input标签[日期控件也有这样的问题]不能编辑的问题,下面是我的解决方法: 1.将下图中框出来的属性删掉即可: 2.兼容火狐浏览器,笔者在火狐中还是不能编辑,去掉下图属性即 ...
- 使用Base64格式的图片制作ICON
使用Base64格式的图片制作ICON的优势是Base64图片可以减少请求次数:加快首屏数据的显示速度:使用这种方式不会对图片压缩 使用base64工具将图片转成字符串 使用站长工具可以将图片转成字符 ...
- BZOJ1458:士兵占领(有上下界最小流)
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...