原文地址:http://blog.sprabbit.com/blog/2013/08/19/introduction-dustjs-3/
Dust在线测试器
首先要介绍一下Dust项目中的一个在线测试器,在了解Dust语法的同时,在这个测试器上尝试应用学到的语法,既可以验证语法是否正确,也可以加强对语法的记忆。进入测试器后可以见到四个框,从左上、左下、右上、右下分别编号为1、2、3、4。测试时在1号框中填入一个Dust模板,然后2号框将显示该模板编译后的结果,再在3号框填入一个JSON对象,4号框中将显示最终的渲染结果。
标签(Tag)
Dust模板以一种嵌入到HTML中的标签的形式存在。Dust标签使用一对花括号包裹,类似于HTML标签使用一对尖括号包裹:
1
|
{name}
|
注释
以下标签将不会产生任何内容,即可用作注释(感叹后之间):
1
|
{! Comment syntax !}
|
键(Key)
一般Dust标签的表示只有两种形式,一种是键,另一种是区段。键是一个最简单的Dust标签,其中包含的花括号中的值称之为键,对应于JSON对象的属性名,对应的属性值一般为简单类型,比如字符串,渲染后将直接以属性值代替整个标签。如果搜索不到任何匹配值,则不会返回任何数据。
1
|
{name}
|
在键名后面可以跟随过滤器,使用竖线分隔,一般用于选择处理“<”,“>”等特殊符号的转义:
<!--[if !supportLists]-->· <!--[endif]-->{name|s} 禁用自动转码
<!--[if !supportLists]-->· <!--[endif]-->{name|h} 强制使用HTML转码
<!--[if !supportLists]-->· <!--[endif]-->{name|j} 强制使用Javascript转码
<!--[if !supportLists]-->· <!--[endif]-->{name|u} 使用encodeURI编码
<!--[if !supportLists]-->· <!--[endif]-->{name|uc} 使用encodeURIComponent编码
<!--[if !supportLists]-->· <!--[endif]-->{name|js} 将JSON对象转换为字符串
<!--[if !supportLists]-->· <!--[endif]-->{name|jp} 将JSON 字符串转换为JSON对象
过滤器也可以进行组合:
{name|jp|h}
一些特殊字符也可以键的形式直接取值输出:
<!--[if !supportLists]-->· <!--[endif]-->{~n} 换行
<!--[if !supportLists]-->· <!--[endif]-->{~r} CR换行
<!--[if !supportLists]-->· <!--[endif]-->{~lb} 左花括号
<!--[if !supportLists]-->· <!--[endif]-->{~rb} 右花括号
<!--[if !supportLists]-->· <!--[endif]-->{~s} 空格
区段(Section)
以下两个标签及其包裹的部分称之为区段,用于循环显示数据。其中“#”为开始标签,“/”为结束标签,其后的键值同样对应于JSON对象的属性名,对应的属性值一般为数组或单个对象,单个对象将被当做一个只有一个元素的数组来对待。模板会按下标对数组中的每个元素调用一次区段包裹着的模板。上一篇中的例子就是利用了区段来循环输出列表元素。
1
|
{#names}....{/names}
|
在区段中可以使用两个特殊的键:
<!--[if !supportLists]-->· <!--[endif]-->{$idx} 表示当前迭代的序号(从0开始)
<!--[if !supportLists]-->· <!--[endif]-->{$len} 表示数组长度
上下文(Context)
Dust对键或区段值的查询与javascript中对作用域链中变量值的查询类似,换而言之使用区段时会临时改变当前的上下文。
例如一个嵌套的JSON对象:
1
2
3
4
5
6
7
8
9
10
|
{
"name":"root",
"anotherName":"root2",
"A":{
"name":"Albert",
"B":{
"name":"Bob"
}
}
}
|
使用区段索值:
1
|
{#A}{name}{/A}
|
则会得到这个对象的A.name
的值:
1
|
Albert
|
因为使用区段时将上下文转移到A属性对应的对象中。
而使用以下区段索值:
1
|
{#A}{anotherName}{/A}
|
因为在对象A的属性中不存在“anotherName”属性,于是Dust会向上查询A所处的上下文,发现存在“anotherName”属性,于是得到:
1
|
root2
|
若往上查找到JSON对象根部间的所有的上下文均无对应属性时将返回空白,索值不会向下查找。
若使用不带路径的区段索值,那么相当于从JSON对象的根部开始定位区段上下文。而使用路径可以指定开始搜索的位置。路径使用标志“.”来标记标签,跟javascript语法类似。依然是这个JSON对象:
1 2 3 4 5 6 7 8 9 10 |
{ "name": "root", "anotherName": "root2", "A":{ "name":"Albert", "B":{ "name":"Bob" } } } |
若我们需要取A属性下的B属性的name则可以表达成这样:
1 |
{A.B.name} |
或者使用路径标记区块:
1 |
{#A.B}{name}{/A.B} |
或者使用单个“.”表示当前上下文对象(当前为字符串):
1 |
{#A.B.name}{.}{/A.B.name} |
规定路径后,首先在指定的上下文进行查找name的值,找不到时不会向上追溯,而是从根部开始查找。
1 |
{#A.B}{A.name}{/A.B} |
上面这个模板将会在A.B中搜索A,因为B并无A属性,所以从JSON对象根部开始找到A属性,从而找到A.name,返回“Albert”,若从根部也无法找到,则返回空白。
修改上下文
我们也可以在一定程度上修改上下文的关系。通过使用冒号“:”可以用冒号后面的键值代替前面的键值的父级上下文:
1
|
{#A:A2} ... {/A}
|
以上这个区段会屏蔽掉A的父级上下文,临时将A2作为A的父级上下文,即在A中找不到目标时不会往上回溯,而去搜索A2下的属性
区段参数
在区段中可以设置参数:
1
2
3
|
{#A.Bfoo="Hi"bar=" Good to see you"}
{foo}{name}{bar}
{/A.B}
|
模板会将参数值替代键值标签,结果为:
1
|
Hi Bob Good to see you
|
参数也可以是键名,但是赋值时的上下文在区段之外:
1
2
3
|
{#A.Bfoo=A.namebar=anotherName}
{foo}{name}{bar}
{/A.B}
|
至此,我们已经可以简单地将模板付诸应用了。下一节将介绍一些逻辑相关的语法。
逻辑区段
?标签
用?
来代替区段标签中的#
时,仅当name
的值为真时,才执行区段主体部分。
1
|
{?name} body {/name}
|
^标签
用^
来代替#
时,仅当name
的值为假时,才执行区段主体部分。
1
|
{^name} body {/name}
|
{:else}标签
当一个区段标签(包括#
、?
、^
、以及逻辑标签等)的值为假时,若区段主体中包含{:else}标签,则执行{:else}
标签以及区段结束标签之间的内容,否则忽略这些内容。
1
2
3
4
5
6
7
|
<ul>
{#friends}
<li>{name}, {age}{~n}</li>
{:else}
<p>You have no friends!</p>
{/friends}
</ul>
|
若friend为空,则仅仅输出:
1
2
3
|
<ul>
<p>You have no friends!</p>
</ul>
|
值的真假
在区段中判断标签的真假的方法与Javascript本身稍有不同,Dust将以下值判断为假:
<!--[if !supportLists]-->· <!--[endif]-->空字符串’’
、””
<!--[if !supportLists]-->· <!--[endif]-->布尔false
<!--[if !supportLists]-->· <!--[endif]-->null
<!--[if !supportLists]-->· <!--[endif]-->undefined
<!--[if !supportLists]-->· <!--[endif]-->空列表[]
其余值均为真值,包括数字“0”,空对象{}
。
拆分(Partials)
拆分是一种将重复使用的模板抽取出来,并在使用到这段模板的模板中直接导入该模板,避免重复劳动的方法。在服务端,一个名为“xxx”的Dust模板通常通常保存在一个名为xxx.dust的模板文件中。我们可以利用模板名来在模板中插入一段来自其他模版文件的模板:
1
|
{>name /}
|
以上是一个自封闭的区段标签,代表将name.dust中的模版插入到当前位置。若文件包含路径,则用双引号包裹:
1
|
{>”dust/name” /}
|
标签中也可以填写参数:
1
|
{>”dust/name” foo=”Hello” bar=” World”/}
|
甚至可以使用动态路径:
1
|
{>”dust/{pathName}” /}
|
区块(Blocks)
通过拆分可以重用一个模版,但是用这种方法来派生模版有一个缺点,就是你需要记得需要在什么位置插入哪个模版,并且对每一个派生出来的模版都要重新布局一次。区块可以解决这个问题,在父模板中使用区块可以方便地在子模板中替换区块中的内容。区块也是一种特殊的区段,定义方法如下:
1
|
{+name /}
|
或者在区段中填写默认内容,当区块没有被替换时,将显示默认内容:
1
|
{+name}default Content{/name}
|
使用区块替换需要在子模板中使用拆分区段(>
)导入父模板,并使用替换区段(<
)进行替换:
1
2
|
{>father/}
{<name}Content{/name}
|
比如一个父模板可以写成这样:
1
2
3
4
5
6
7
8
9
|
<divclass="page">
<h1>{+pageHeader}PayPal{/pageHeader}</h>
<divclass="bodyContent">
{+bodyContent/}
</div>
<divclass="footer">
{+pageFooter}Contact Us {/pageFooter}
</div>
</div>
|
然后保存为shared/base_template.dust文件,然后定义子模板:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
{! 首先导入父模板 !}
{>"shared/base_template"/}
{! 然后定义对应的部分 !} {<bodyContent}
<p>These are your current settings:</p>
<ul>
<li>xxxx</li>
<li>yyy</li>
</ul>
{/bodyContent}
{<pageFooter}
<hr>
<ahref="/contactUs">About Us</a> |
<ahref="/contactUs">Contact Us</a>
{/pageFooter}
|
应用Dust模板
至此,Dust自带的基本功能语法已经介绍完毕,目前大家可能只在测试器中使用过模板,以下将介绍如何直接在前端中应用模板。
编译
之前也介绍过,Dust是编译型模板,意思则是若需应用模板,首先要将模板可执行化,即将模板变成可执行的代码。如果你使用过Dust测试器,那么你会发现在你输入模板后,会在2号框中显示一个函数定义,那就是编译生成的代码。使用编译型模板有一个好处,就是当模板编译好之后,若需要重复使用模板,不需要每次都对模板重新进行分析,加快模板解析的速度,而且,模板可以预先编译好保存在服务器,甚至让前端连第一次编译的时间都节省了。
因此Dust库有两种发行版本:
<!--[if !supportLists]-->· <!--[endif]-->dust-core-2.0.2.js
dust-full-2.0.2.js编译模板的方法很简单,使用完全版的dust.compile()方法:
1 |
var compiled = dust.compile("Hello {name}!", "intro"); |
其中第一个参数为模板字符串,第二个参数为模板名,函数将返回包含编译好的可执行代码的字符串。这个操作不会注册这个模板,仅进行编译,此时仍不可通过模板名来调用这段代码。
注册
如果直接执行一遍compiled中的代码,则模板会按之前指定的名字注册到dust,从而可以通过模板名来调用该模板。但若compiled代码未被执行过,则需要在渲染前手动将其注册到dust中,注册的方法很简单:
1
|
dust.loadSource(compiled);
|
渲染
<!--[if !supportLists]-->· <!--[endif]-->通过编译注册可以让多套模板处于就绪状态,对于这些模板,我们可以直接用它将JSON对象渲染成HTML文本,通过调用dust.render()方法。
1 2 3 |
dust.render("intro", {name: "Fred"}, function(err, out) { console.log(out); }); |
<!--[if !supportLists]-->· <!--[endif]-->这个方法接受3个参数,第一个为模板名,第二个为JSON对象,第三个是一个接受两个参数的回调函数。执行这个方法后Dust会使用注册好的对应模板对JSON对象进行处理,得出一个渲染结果字符串,然后调用回调函数,其中第一个参数包含了在处理过程中出现的错误信息,第二个参数就是渲染结果字符串。一般会在回调函数中将渲染结果插入到当前的DOM结构中,以便在浏览器中显示渲染结果。
区块和拆分
一般使用文件来保存模板并且使用区块和拆分是让Dust作为服务端模板时应用的技术,因为在客户端Javascript中无法很方便地对分布式文件进行操作。但是我们可以通过在本地部署模板数据,编译成可执行代码并用一个js文件来保存的方式来使用区块和拆分。
若在Linux平台则直接在终端安装npm和dust并使用dustc命令编译成代码,得到js文件。
1
2
|
$ npm install dustjs-linkedin
$ dustc input.dust output.js
|
或者在js引擎中使用dust.compile(),将模板复制到第一个参数,指定第二参数为其不带后缀的文件名,并将结果输出到js文件。
1
2
3
|
varoutput1=dust.compile(partialStr,"partial");
varoutput2=dust.compile(baseStr,"base");
varoutput3=dust.compile(childStr,"child");
|
最后在HTML中导入所有生成的js文件即可使用。
1
2
3
|
<script type="text/javascript"src="partial.js"></script>
<script type="text/javascript"src="base.js"></script>
<script type="text/javascript"src="child.js"></script>
|
注意此时不再需要使用dust.loadSource()来注册,因为script标签将js文件执行了一次,已经将模板注册好了。此时已可使用dust.render()进行渲染。
相关推荐
Dust模板的核心特性包括响应式设计,这意味着无论用户使用桌面电脑、平板电脑还是智能手机访问,网站都能自适应地呈现出最佳的视觉效果。这种特性对于提升用户体验和搜索引擎优化(SEO)至关重要,因为它确保了在...
DustJS 是一个支持浏览器和 Node.js 的异步模板引擎。特点:async/streaming operationbrowser/node compatibilityextended Mustache/ctemplate syntaxclean, low-level APIhigh performancecomposable templates ...
哈皮粉尘测试 这是为了使用 hapi-dust 视图引擎测试 Hapi。 用法 npm install node start 访问/以加载模板化版本,访问/ /stream以获取简单的 Stream 版本。
如果您的脚本包括带有部分模板的模板: <p>hello</p>p>{>"some/template"/}dustjs-browserify模块还将包括并浏览some / template.dust模板。安装该软件包可在npm上以以下方式获得: npm install dustjs-...
1. **模板语法**:Dust模板使用特殊的语法,如`{}`来包裹变量,`{#}`和`{/}`用于控制结构(如循环和条件语句)。例如,`{name}`会输出对应的变量值,而`{#array}`和`{/array}`则用于遍历数组。 2. **上下文...
`check-locales`工具是JavaScript的一个实用程序,主要用于确保.properties文件与关联的Dust模板保持同步和正确性。这个工具对于多语言支持和国际化(i18n)项目来说至关重要。 .properties文件通常用于存储应用...
在这个 "try_dust" 示例中,你可能看到一个简单的HTML文件(如 `index.html`),里面包含一个Dust模板,以及一个JavaScript文件(如 `app.js`)来加载数据和初始化Dust。以下是基本步骤: 1. **HTML模板**: `index....
6. **社区支持**:Dust3D还拥有活跃的用户社区,用户可以分享建模技巧、模板和资源,促进了学习和创作的互动。 通过压缩包文件“huxingyi-dust3d-1b2cba9”,我们可以推测这可能包含Dust3D的源代码、资源文件或者...
Vim-dust 是一个专门为 Vim 编辑器设计的插件,它提供了对 Dust 模板语言的语法高亮支持。Dust 是一种轻量级的、非侵入式的JavaScript模板引擎,常用于构建动态Web应用,以实现数据驱动的视图渲染。Vim-dust 插件的...
Marko 视图引擎现在可以在代码中的其他地方使用了: var templatePath = require . resolve ( './hello.dust' ) ; var template = require ( 'view-engine' ) . load ( templatePath ) ; // Callback-style ...
不推荐使用灰尘项目不再维护。粉尘 预编译模板输出的问题应在灰尘上报告。安装 $ npm install --save-dev broccoli-dust用法 var dust = require ( 'broccoli-dust' ) ;tree = dust ( tree , name ) ;原料药灰尘(树...
防尘包 浏览器和 node.js 的异步模板 安装 将dust添加到kanso.json的依赖项部分。 ... "dependencies" : { "dust" : null , ... } 运行kanso install以获取包。
熟悉该过程后,可以使用以下命令安装此插件: npm install grunt-dust --save-dev 插件安装完成后,可以使用以下JavaScript代码在您的Gruntfile中启用该插件: grunt . loadNpmTasks ( 'grunt-dust' ) ; 该插件旨在...
尘压贡献者: / , 网址: : 标签:灰尘,WordPress,灰尘,灰尘至少需要:4.2.0 经过测试:4.9.0 许可证:GPLv2或更高版本许可URI: : 描述WordPress主题框架,用于使用Dust.js模板引擎和单独的数据模型编写模板...
不推荐使用灰尘项目不再维护。口香糖 预编译模板输出的问题应在灰尘上报告。安装 $ npm install --save-dev gulp-dust用法 const gulp = require ( 'gulp' ) ;const dust = require ( 'gulp-dust' ) ;gulp . task ( ...
ECT开发者称,与其他引擎(如Dust、Hogan.js、Fest、Handlebars.js、doT、Swig、Eco、EJS、CoffeeKup和Jade等)相比,ECT目前是最快的,见基准测试。你可以在客户端或Node.js服务器端使用ECT。 ECT还包含其他一些...
6. **模板渲染**:使用Dust.js处理视图渲染。创建登录和注册页面的模板,使用Dust语法插入动态内容。例如,错误消息可以显示在表单下方,提示用户输入不正确。 7. **中间件处理**:使用Passport的`authenticate()`...
dust-recursive-loader是一个Webpack加载器,它将DustJS模板文件编译成其JavaScript模板函数。 特征: 返回可以使用上下文和回调直接调用的函数。 它会查找所有布局和部分依赖项,并将它们添加到您的捆绑包中。 ...
klei-dust是一个帮助器(受启发),它使用模板作为视图以及 。 好处 klei-dust的主要优点是它支持部分和基本模板的相对路径。 例如,你可以有一个基本模板base.dust在/views/base.dust并在子模板/views/child.dust...
通过学习和使用ReadWiser,开发者可以深入了解如何利用Node.js构建Web应用,掌握Foundation框架的使用,以及如何将Dust模板引擎集成到项目中进行动态内容渲染。此外,对于想要提升前端和后端技能的开发者来说,这个...