handlebars.php,Handlebars partials 隐藏的力量
一个项目的机会再加上我自己的探索,让我对Handlebars partials有了更深的理解。事实证明,你可以做得比我了解的更多。
我最近在负责一个小项目,只有很少的静态页面。因为太小了,我们最开始没有使用模板系统。当项目开始往深一层推进时,我们发现把静态页面拆分成partials & layout的模板明显更好。
我们以前用过handlebars-layouts并且很喜欢它提供的那些特性。我本来想同时安装Handlebars和handlebars-layouts,但是又感觉过于累赘了。
我在想有没有可能只使用Handlebars而不用额外的handlebars-layouts库?
我并不是想吐槽handlebars-layouts,我们以后可能还会用到这个项目。但是我想试试只用Handlebars partials来实现一些handlebars-layouts通过helper来实现的一些特性。
花了一些时间来评估项目需求后我问自己:handlebars-layouts helpers提供的哪些特性是我需要的?根据过去的经验,我列出了如下helpers:
{{#extend}} layouts的能力
{{#embed}} partials的能力
能像{{#block}} 和 {{#content}}一样配合
列出来后,我开始查Handlebars partials文档来看看行不行。然后我发现我从来没有利用到partials的全部潜力,只要做一点小小的努力就可以让它们实现我的需求。有两个特性吸引了我:partial blocks和inline partials。
我兴奋地意识到Handlebars partials可以做到比我想象中多得多的事情并马上开始了工作。
Partials基础
在开始前,还是先看一看基本partials, partial blocks 和 inline partials。
基本partials就像这样:
{{> content-block }}
它会试图找到一个命名为content-block的partial进行渲染,否则就报错。
Handlebars partial的文档上写:
The normal behavior when attempting to render a partial that is not found is for the implementation to throw an error. If failover is desired instead, partials may be called using the block syntax.
渲染一个partial的默认行为是,如果没找到就报错。如果要进行错误处理,就要用block的方式来使用。
partial block就像这样:
{{#> content-block}}
Default content
{{/content-block}}
这样写有一个好处,就是当content-block没有找到时,partial block里面的部分就会被渲染,像上面就会渲染“Default content”。
而inline partial就像这样:
{{#*inline "content-block"}}
My new content
{{/inline}}
文档里是这样说的:
Templates may define block scoped partials via the inline decorator.
通过使用inline修饰符,可以在模板中定义块级partials。
inline partial允许你临时创建partials。如果页面中有一个content-block partial block,然后我们创建了content-block inline partial的话,inline partial中的内容(“My new content”) 就会替换partial block中默认内容。inline partial同样可以替换基本partials,只是基本partials没有默认内容而已。
了解完这些后我们就可以开始了。
目录结构
我想同时拥有layouts/、includes/和pages/,目录结构看起来如下:
src/
├── pages
│ ├── page-one.hbs
│ └── page-two.hbs
└── partials
├── includes
│ ├── hero.hbs
│ └── footer.hbs
└── layouts
└── base.hbs
为了进行渲染使用了Gulp + gulp-compile-handlebars,在htmlgulp任务中把src/pages/*.hbs当成source目录,就像下面这样:
// gulpfile.js
const handlebars = require('gulp-compile-handlebars');
const rename = require('gulp-rename');
gulp.task('html', () => {
return gulp.src('./src/pages/*.hbs')
.pipe(handlebars({}, {
ignorePartials: true,
batch: ['./src/partials']
}))
.pipe(rename({
extname: '.html'
}))
.pipe(gulp.dest('./dist'));
});
需要注意,我们口中的“page”, “include”和“layout”,本质上都是Handlebars partial,这就是保证可扩展性的关键。一旦了解了这个,新世界的大门就打开了。
Layouts, pages 和 includes
再来分别看看每个文件:
Layouts 文件
首先是layouts/base.hbs:
{{!-- layouts/base.hbs --}}
{{#if title}}
{{title}}
{{else}}
Base Page Title
{{/if}}
{{#> head-block}}
{{!-- Custom
content per page could be added. --}}
{{/head-block}}
{{#> hero-block}}
{{!-- Hero content goes here. --}}
{{/hero-block}}
{{#> footer-block}}
{{!--
The `includes/footer` partial is the default content,
but can be overridden.
--}}
{{> includes/footer }}
{{/footer-block}}
{{#> scripts-block}}
{{!-- Custom scripts per page can be added. --}}
{{/scripts-block}}
有些值得注意的地方,拆开来单独看:
{{#> head-block}}
{{!-- Custom
content per page could be added. --}}
{{/head-block}}
引入了一个虚构的main.css。然后设置了head-block,当一个具体的page继承此layout时在这里传入
中的内容(注:就跟handlebars-layouts的{{#block}} helper一样)。
{{#> hero-block}}
{{!-- Hero content goes here. --}}
{{/hero-block}}
{{#> scripts-block}}
{{!-- Custom scripts per page can be added. --}}
{{/scripts-block}}
跟head-block一样,我们在hero和scripts部分都用了Handlebars partial blocks。在同一套模板有不同的内容和scripts的时候,显得更加灵活。
{{#> footer-block}}
{{!--
The `includes/footer` partial is the default content,
but can be overridden.
--}}
{{> includes/footer }}
{{/footer-block}}
footer部分我们又用了Handlebars partial block,不同的是我们用了{{> includes/footer }}基本partial来指定默认内容。
当footer-block没有被传入内容时就会渲染默认内容。所有代码中,我们都用的Handlebars注释(注:这些注释不会被渲染到HTML中,如果你用HTML注释就会被渲染到HTML中,因为partial block中所有内容都会被渲染)。
page 文件
拼图的下一部分就是page partial。我们也用到了Handlebars partial blocks,同时还有Handlebars inline partials,下面是pages/page-one.hbs的示例:
{{!-- pages/page-one.hbs --}}
{{#> layouts/base title="Page One" }}
{{#*inline "hero-block"}}
{{> includes/hero
hero-src="img/hero-1.png"
hero-alt="Hero 1 alt title"
}}
{{/inline}}
{{/layouts/base}}
同样拆开来看看:
{{#> layouts/base title="Page One" }}
...
{{/layouts/base}}
这里又用到了Handlebars partial block。但是这次,我们用它来继承layouts/base(注:就跟handlebars-layouts {{#extend}} helper一样),同时设置了page的title(注:用到了partial 参数特性)。
{{#*inline "hero-block"}}
...
{{/inline}}
这是我们第一次用到Handlebars inline partial。这个inline partial被传入layouts/base然后被其中的hero-block注入(注:用法就跟 handlebars-layouts 的 {{#content}} helper 一样)。
{{> includes/hero
hero-src="http://fpoimg.com/500x200"
hero-alt="Hero 1 alt title"
}}
最后我们引入indludes/hero基本partial(注:就跟handlebars-layouts {{#embed}} helper一样)。
includes 文件
includes/*.hbs可以被layouts 和 pages引用。既然都用到了,那就看看大概是什么样子的:
{{!-- includes/hero.hbs --}}
没什么开创性的东西,只是简单地渲染传入的hero-src 和 hero-alt(注:可以改进的地方:用{{#if}}{{else}}来判断参数是否为空)。
再看看includes/footer.hbs:
{{!-- includes/footer.hbs --}}
This is some default footer content.
没啥特别的,这就是layouts/base中footer的默认内容。
最后成果
来概括一下所有东西。
layouts/base.hbs
充当基础layout文件
使用partial blocks定义默认和动态内容
pages/page-one.hbs
充当page文件
使用partial block来继承基本layout
使用inline partials填充内容到layout中的 partial blocks
includes/*.hbs
partials可以被 layouts 或 pages 引用
可以在partial block或inline partial中使用
然后就是最后渲染出的page-one.html文件,看起来就是这样:
Page One
This is some default footer content.
让我们再试试使用同一个layout,但改一些东西,就叫它pages/page-two.hbs好了:
{{!-- pages/page-two.hbs --}}
{{#> layouts/base title="Page Two" }}
{{!-- Let's add a second stylesheet for this layout. --}}
{{#*inline "head-block"}}
{{/inline}}
{{!-- Let's change the hero image for this layout. --}}
{{#*inline "hero-block"}}
{{> includes/hero
hero-src="http://fpoimg.com/400x400"
hero-alt="Hero 2 alt title"
}}
{{/inline}}
{{!-- Let's override the "footer-block" content. --}}
{{#*inline "footer-block"}}
We are now overriding the default "footer-block" content with this content.
{{/inline}}
{{!-- Let's add a script for this layout. --}}
{{#*inline "scripts-block"}}
{{/inline}}
{{/layouts/base}}
渲染出来就是这样:
Page Two
We are now overriding the default "footer-block" content with this content.
这样我们就用同一个layout渲染出了两个不同的页面。
感谢
我们用Handlebars 的partial blocks, inline partials, basic partials 和partial parameters模拟出了handlebars-layouts的{{#extend}, {{#embed}}, {{#block}} 和 {{#content}} helpers。
这是一次有趣的尝试,让我更好地理解了Handlebars partials。注意在不同的项目中,我们必须先评估库提供的特性,有哪些是需要的,哪些是不需要的,没有一个完美的解决方案(注:有些特性是无法模拟的,比如 {{#content}} 的 append 和 prepend,又比如content作subexpression时,用conditonal blocks 检查content是否为空)。
如果你想要了解更多,可以看看这个项目,试试各种组合,看看能不能挖掘出更多的Handlebars partials的潜力。
handlebars.php,Handlebars partials 隐藏的力量相关推荐
- Handlebars partials 隐藏的力量
一个项目的机会再加上我自己的探索,让我对Handlebars partials有了更深的理解.事实证明,你可以做得比我了解的更多. 我最近在负责一个小项目,只有很少的静态页面.因为太小了,我们最开始没 ...
- handlebars java,handlebars踩坑之旅
1. each的使用方法(遍历数组或者对象) {{include "tpl/components/page3-school-slide/each-slide" data='[ { ...
- Handlebars.js入门教程
转自https://segmentfault.com/a/1190000002796397 概述 刚接触前端的时候,师傅就给我推荐了Handlebars,自己也蛮喜欢它的语法.到现在,Handleba ...
- Handlebars总结
概念 Handlebars 是一种简单的 模板语言. 它使用模板和输入对象来生成 HTML 或其他文本格式.Handlebars 模板看起来像常规的文本,但是它带有嵌入式的 Handlebars 表达 ...
- handlebars html转义,介绍 | Handlebars 中文文档 | Handlebars 中文网
# 介绍 # 什么是 Handlebars? Handlebars 是一种简单的 模板语言. 它使用模板和输入对象来生成 HTML 或其他文本格式.Handlebars 模板看起来像常规的文本,但是它 ...
- Handlebars模板引擎
介绍 Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板.它采用"Logic-less template"(无逻辑模 ...
- Handlebars的基本用法
使用Handlebars,你可以轻松创建语义化模板,Mustache模板和Handlebars是兼容的,所以你可以将Mustache导入Handlebars以使用 Handlebars 强大的功能. ...
- Handlebars.js 模板引擎
介绍 Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板.它采用"Logic-less template"(无逻辑模 ...
- 作为一名前端开发工程师,你必须掌握的WEB模板引擎:Handlebars
为什么需要使用模板引擎? 关于为什么要使用模板引擎,按照我常说的一句话就是:不用重复造轮子了. 简单来说,模板最本质的作用是"变静为动",一切利于这方面的都是优势,不利于的都是劣势 ...
最新文章
- Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法
- 神策数据入选《2020 爱分析·数据智能厂商全景报告》
- 机器学习中的维度灾难
- python from sys import argv_笨方法学python之import sys与from sys import argv的区别
- Pin code码已被重置
- 工程计价里面的表以及相关税额的计算
- K8S的HelloWorld之旅
- LeetCode 241. 为运算表达式设计优先级(动态规划)
- uniapp H5页面打包发布
- pythonsqlite事务_python sqlite3 的事务控制
- 【BZOJ2151】种树,贪心+Splay乱搞
- git rebase 合并中间的提交
- GPU-Z:显卡体质、显卡各传感器实时状态的查看
- 2021年最优秀的新闻APP或许是这两个(国内没上架)
- 海信电视root后误删软件无法进入主页键解决办法
- dual thrust 交易_国债期货常见的量化对冲交易策略
- mht转html保留图片,【JAVA】mht文件转html
- JDK8新特性02 Lambda表达式02_Lambda语法规则
- 树莓派红外火焰传感器
- 基于opencv实现桌面图标识别
热门文章
- Linux文件的rwx含义,Linux文件权限rwx简单了解(示例代码)
- # 个人日记-电影《长津湖》观后感-20211008
- Python+Vue计算机毕业设计创意家居装饰购物网站e1gj6(源码+程序+LW+部署)
- redis cluster 操作命令
- 小程序是移动互联网下一站 暂不能做游戏|
- C++操作.json文件
- 什么是语音直播源码,语音下直播系统可以做什么?
- H5APP中使用vue拨打用户电话
- 普通字符串转,16进制,base64互转
- Sakura editor一些使用技巧