从官方文档去学习之FreeMarker

一、前言上一篇 <从现在开始,试着学会用官方文档去学习一个技术框架> 提倡大家多去从官方文档学习技术,没有讲到具体的实践,本篇就拿一个案例具体的说一说,就是FreeMarker,选择这个框架没什么特别的含义,最近要用,就拿这个做个典型。二、套路上篇文章最后说到技术学习没有套路,无招胜有招,无招即是有招,解读一下实际上就是说 本身还是有些招式套路,但是要灵活运用,不要什么都往上套,应该忘掉固有的套路,让其化为你的一种本能,见招拆招。 下面就介绍一种常规学习套路给大家,如下图:下面就根据上面的套路结合FreeMarker官网溜一遍,来学习FreeMarker,重点在前4部分,后面两部分需要一些积累和经验后才更容易上手,所以本篇不会重点讲三、实践3.1 了解框架 首先我们应该了解FreeMarker是用来干什么的,这时候我看打开官网 https://freemarker.apache.org/ 上图来自官网首页上方的导航,依次为 Home(主页)、Manual(手册)、JavaApi(API接口)、Contribute(贡献)、 Report a Bug(反馈BUG)、 Download(下载) , 单词不认识,找工具翻译一下,没有别的办法,上篇也提到了。从字面意思理解可以看出跟我们有关的就是标红的那4个,好的来看看首页的介绍(大部分框架首页都会有简要介绍,说明框架的用途): 这是首页的两段介绍,自行翻译一下,这里就不在翻译了,解读一下,我们从这两段内容中可以得到如下信息:(1)这是一个Java模板引擎(2)用模板语言(FTL)编写(3)基本思想:java或其他编程语言准备数据,FreeMarker显示数据,配合官方给的图,更直观(4)在模板中,您关注的是如何显示数据,而在模板之外,您关注的是显示什么数据,这也是所有模板引擎解决的核心问题 数据与显示分离(5)用于MVC模式,有助于分离Java开发人员和web设计人员,设计人员不会在模板中面对复杂的逻辑,并且可以在不需要程序员更改或重新编译代码的情况下更改页面的外观,这里就说明了模板的好处,面试问你,为什么用模板技术啊,结合上面的一点就可以完美回答这个问题了(6)不依赖Servlet,也就是web环境和非Web环境都可以使用(7)更多细节内容看 manual (手册)通过解读官方的文档,我们就可以得到以上7个方面的信息。也就了解了Freemarker的作用、基本思想、好处、应用环境,这些东西,相信在很多FreeMarker的教程中,都不会这么详细,而且上面的信息基本上只要你把英文翻译过来都可以直观看到,我并没有做太多总结性归纳。 这是基本内容,首页还标出了一些特性我们再来看一下解读一下得到的信息如下(1)强大的模板语言,支持条件块、迭代、赋值、字符串和算术操作等(2)零依赖,任何输出格式,可以从任何地方加载模板(3)支持国际化(4)支持xml数据模型,也就是可以将xml数据填充到模板上(5)支持java对象暴露在模板,简单理解模板中可以调用对象的方法结合上面的基本内容和特性部分的内容,相信大家对freemarker有了较为完整的认识,包括能不能满足自己的一些场景,也会有一些基本的判断,方便技术选型。3.2 Helloworld看完基本内容,有了大致了解后,是不是迫不及待想去敲代码试一下,小阶段的输出成果更容易促使学习的动力。看文档首页显然没有告诉我们怎么用,怎么去开始写代码,但提到了更多内容看manual,那我们就点到manual去看一下从这里我看看到了Getting Started(开始),大部分的官网都会有Getting Started,点进去看一下,这里要多做一件事,写代码肯定要使用freemarler的jar,我们就从download去拿一下,进到download可以看到,我们可以直接下freemarker.jar、源码,或者通过maven引入,这里大家随意,导入工程,然后回到刚才的地方,看quick start三块内容(1) 模板 + 数据模型 = 输出(2) 一睹数据模型(3) 一睹模板分别点进去看一下,可以了解到(1) 模板有表达式和指令(2) 数据模型是树形结果但是我们没有看到代码,只看到一段模板代码和最终的结果输出,这里没有怎么办?我们再扫一眼目录,发现这里还有个Getting Started(一些框架官网没有直接给demo,我们可以去框架托管代码(github、gitee)的地方去找一下,基本上都会有demo)然后看一下它的分类是 Programmer’s Guide(程序员指南),那就应该是这里了,点进去看一下,可以看到,除过最后最后的 Putting all together, 其他部分是使用模板的每一个步骤,分为:创建配置实例 -> 创建数据模型 -> 获取模板 -> 合并数据模型到模板,这也是使用freemaker的基本步骤,分步骤的就不看了,我们直接看最后的Putting all together(所有合到一起的内容)测试类import freemarker.template.;import java.util.;import java.io.;public class Test { public static void main(String[] args) throws Exception { / ———————————————————————— / / You should do this ONLY ONCE in the whole application life-cycle: / / Create and adjust the configuration singleton / Configuration cfg = new Configuration(Configuration.VERSION_2_3_27); cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates")); cfg.setDefaultEncoding(“UTF-8”); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); cfg.setLogTemplateExceptions(false); cfg.setWrapUncheckedExceptions(true); / ———————————————————————— / / You usually do these for MULTIPLE TIMES in the application life-cycle: / / Create a data-model / Map root = new HashMap(); root.put(“user”, “Big Joe”); Product latest = new Product(); latest.setUrl(“products/greenmouse.html”); latest.setName(“green mouse”); root.put(“latestProduct”, latest); / Get the template (uses cache internally) / Template temp = cfg.getTemplate(“test.ftlh”); / Merge data-model with template / Writer out = new OutputStreamWriter(System.out); temp.process(root, out); // Note: Depending on what out is, you may need to call out.close(). // This is usually the case for file output, but not for servlet output. }}数据模型/* * Product bean; note that it must be a public class! */public class Product { private String url; private String name; // As per the JavaBeans spec., this defines the “url” bean property // It must be public! public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } // As per the JavaBean spec., this defines the “name” bean property // It must be public! public String getName() { return name; } public void setName(String name) { this.name = name; }}模板 test.ftlh<html><head> <title>Welcome!</title></head><body> <h1>Welcome ${user}!</h1> <p>Our latest product: <a href="${latestProduct.url}">${latestProduct.name}</a>!</body></html>相信不出意外,复制粘贴到自己的工程里,就可以正常运行了,至此一个helloworld就算OK了,对于代码的含义,可以直接查javaApi, 可以看分步骤的内容有解释。至此我们对freemarker应该有了更直观的认识和理解,也基本知道了使用的套路3.3 熟悉配置为什么要熟悉配置,很多框架的功能支持、 性能调优实际上做的就是配置参数的调整,所以说比较重要,我们来看一下,回到manual首页,找配置相关的字眼,发现就是它了吧,大概点进去看一下更多的图就不贴了,总之我们指导这里就是介绍配置属性的地方,详细内容大家自己看一看,这里有一个比较重要的点就是模板加载器,大家自己查阅熟悉一下。3.4 更多API熟悉完配置,我们需要了解一些API的使用,这里就不展开了,点到javaApi,自行查阅,这里就不展开说明了。3.4 表达式、指令这里的内容在上面的套路图中没标,那个图我表达的是一个通用的套路,这里算套路图中[更多基础API]一种吧。表达式、指令是对与模板来说的,也就是输出数据的一些命令。浏览文档相关内容找模板、表达式、指令相关的关键字,就可以锁定相关内容主要在单纯的表达式、指令使用都很简单,这里不多讲了。3.5 高级用法所谓高级用法也就是一些提升性能的配置、自定义扩展、一些指令、表达式之类的,这需要大家熟悉基本的使用、配置、api和文档的相关介绍。这里暂不展开,相信有了前面的基础掌握一些技巧和方法,这里来说不是难事。3.6 原理、源码这里针对有兴趣,想深入学习的人,写到这是为了保证套路的完整性,这里也不展开,也不是本篇内容的重点。四、总结本篇重点是带大家从官网去学习一个技术框架,至少用到一些配置、api知道怎么去查,要学习一个新技术的时候大概需要怎么做,还提了一个基本的学习套路,希望能给需要的人一些帮助。没看上一篇的建议看一下。Over。 ...

January 27, 2019 · 2 min · jiezi

Hello 2019! Hanjst/汉吉斯特 模板语言及引擎创新发布

Hello 2019! Hanjst/汉吉斯特 模板语言及引擎创新发布。值此一元复始之际,恭祝 朋友们新年万事如意!寄望 Hanjst/汉吉斯特能帮助大家从各种模板中解脱出来,为人类做出更大的贡献。1. 背景网页模板语言/引擎缘起于 MVC 思想的引入。当软件项目膨胀复杂到足够大时,软件研发人员与UI/UE设计人员就需要分别独立出来,其中设计制作人员工作的V(View)部分需要用模板语言与引擎。模板语言及引擎的设计与研发工作是一项既简单又复杂的工作。简单地说,模板就是一种变量替换的工作,在模板中预留相应的占位符和变量标记,模板引擎在工作时在相应的占位符将对应的变量替换为实际对应的数值即可。复杂地说,模板语言是一种全新表达语言的设计,设计一门语言,其难度是可想而知的,这门语言要能够满足日常沟通之需要,首先或入门的是语言设计者要考虑的,是该模板语言能够普遍接受和广泛使用,这样语言才有生命力。无疑,简洁而表意丰富是重要而优先的考虑项。先行者已经在模板领域创制出大量符合各种需求的模板语言与模板引擎,这里是一个简单的归集 -R/U2SJ , 为了更好的梳理其发展类别,我们绘制了一个 Mind map:Fig1. 网页模板语言分类概括2. 问题讨论如在Fig1中所展示的,模板语言及引擎有很多种类,每个分类下面又有不同的应用实例,可谓多姿多彩,琳琅满目。实际上,在网络上搜索一下可能会发现,网页模板语言和引擎多到不胜枚举,连JSP、PHP这样的开发语言都可以归类为某种模板语言的范围。通过脑图的分析,我们发现在这一领域还有两个问题没有得到解决,或者没有得到很好的解决:1)服务器端,有没有一种模板语言与引擎可以实现跨开发语言的? 2)客户端/浏览器终端,有没有一种模板语言与引擎能够不需要Script tags的?针对第一个问题,我们搜索了多次,发现的确有针对不同开发语言而设计的模板语言与引擎,多数只是针对某几种主流语言开发了模板编译引擎,只是做到“准跨开发语言”,另外就是,这些看似高级的模板语言与引擎,大多数都是私有软件,非开源,需要购买获取授权才能使用。至于第二个问题,Script tags,一般的定义是这样的,如果我们在客户端使用JavaScript来写一个模板,通常都需要先声明一段区块头部,然后完事之后再声明一下区块尾部,这个区块的头尾部使用Script tags来实现的,如下:<script id=“template” type=“x-tmpl-mustache”>Hello {{ name }}!</script>这是令人不悦的,为何要表述一句 “Hello {{name}}”, 无辜地多写了第一行和第三行,不能省掉吗?令人无可忍受地还有其他的,3)logicless 。如果一种模板语言无法表达逻辑,这是什么逻辑?4){{name}}。为何必需用两个“{{” ,而不是一个“{”?5)<#list>. 为何要用 “<#” , 能再简洁易懂些吗?Fig2 腾讯理财通客户端等JavaScript模版从 Fig2 中我们可以看到这些令人不满意等地方,函数等调用 | f2y | n2t 借用了命令行管道等意思,如果有参数呢?能否写成:f2y(n2t(IMonthProfit)) orIMonthProfit.n2t().f2y()通过Fig2 我们还发现 模版语言,尤其是 JavaScript 模版语言在App上应用等依然存在,模版等使用并没有随着Web向App转换而减少。于是,怀着这些不满意,我们设想满足以下需要来设计一套新的模板语言与引擎:A)跨开发语言,与服务器开发语言不做绑定,同时开源,免费使用;B)去掉 Scripts tags;C)基于JavaScript提供,同时与服务器端一致强大而复杂的表达、表示能力。如能满足以上,我们在继续研制 -GWA2 / -吉娃兔 的道路上,有望一通各个开发语言的模板引擎,而不是在开发 Java 版本的 GWA2时 选择 Velocity, 在 开发 PHP 版本的 GWA2 时选择 -Smarty 等问题。以语言学家的视角来设计这套模板语言与引擎,以工程师的思维来实现语法、语义的程序化表达,这就是 Hanjst 模板语言及引擎。3. Hanjst, 汉吉斯特 模板语言及引擎Hanjst是一种基于JavaScript的模板语言及解析引擎,她可以运行在客户端,也可以运行在服务器端。Hanjst能够表述逻辑控制,能够实现与服务器端模块语言相同的功能。特征/功能Hanjst运行在客户端时完全客户端解析,节省服务器端计算资源;Hanjst模板语言独立,不与服务器端开发语言做任何绑定;纯粹的MVC,层间数据用JSON格式传递;常见模板语言功能全支持,附带复杂而强大的JavaScript编程能力;无学习成本,直接使用JavaScript书写模板语言;开源的,免费使用;….Han 是我妻子的姓(韩), 也是出现我女儿和儿子名字中的音节。Han 也是中文“汉族”的意思。Hanjst 模板语言及引擎设计用来终止在HTML模板语言领域不断地“再造轮子”的活动,尽管这听起来有些怪异。Hanjst 的语法与基于 PHP 的Smarty语言有相似的地方,原因是我们借鉴了 Smarty的一些设计,之所以如此,是我们赞同 Smarty 在语言精炼方面精益求精的探索( -R/x12SU )。Note that the PHP syntax uses 5 punctuation characters to display asimple variable: <?=?>, whereas Smarty uses 2: {}.Hanjst 依托JavaScript内部对象及函数的功能,赋予了在模板中直接调用这些功能的能力,实现了媲美服务端模板语言一致的表示、表达能力。如表达截短一个字符串:{$myString.substring(0, 10)} 4. 发展规划及设想Hanjst 模板语言及引擎已发布在 -GitHub 上,地址为: https://github.com/wadelau/Ha… 。Hanjst 模板语言及引擎的样例展示地址, -Hanjst , -R/j2SP 。 现在就可以点开尝鲜。Hanjst 模板语言及引擎的参考手册在编辑中,不日将在线发布。Table of ContentsI. What is Hanjst?1.Hanjst Installation2.Basic SettingsII. Hanjst for Template Designers3.Syntax and Semantic4.Variables5.Modifiers on Variables6.Built-in Functions7.Warnings and ErrorsIII. Hanjst Template for Programmers8.JSON Data9.Includes10.Compile and CacheIV. Search Engine Optimization11.HTML Head Element12.Plain Content Div Element13.Robot-oriented LinksV. Advanced Applications for Hanjst14.Embedded in HTML Elements5. 不足及改进工作目前已知的不足之一是在客户端运行编译模板文件时,对搜索引擎不够友好。针对这一问题,我们提供了优化HTML head, 曝露 Hanjstjsondata 等方式进行补充。其他的,请大家试用并反馈。2019年元旦,Hanjst/汉吉斯特 正式对外公布。-R/U2SK ...

January 20, 2019 · 1 min · jiezi

Nunjucks使用正则表达式示例

我在使用egg.js时,他用的模板引擎是Nunjucks,其中有个地方需要用到正则,可是官方文档基本上写了跟没写一样,官方的正则表达式。于是我便去找例子了。正则表达式在Nunjucks中使用正则表达式的示例:{% set regExp = r/^foo.*/g %}{% if regExp.test(‘foo’) %} Foo in the house!{% endif %}那么这个就会被正常显示。其他的表达式也是可以的。例如:<!– 有个后台存储的未验证的手机号码(mobile)在前端显示,如果格式正确则显示,不正确则显示“暂无” –>{% set regExp = r/^\d{11}$/g %}<span>号码:{{mobile if regExp.test(mobile) else ‘暂无’}}</span>这两个例子应该看得懂吧。正则这块我并没有看源码,因为搜索出来了,我这里参考的regex exmaple?后来发现其实很多方法文档并没有写出来,这时候可能真的需要看看源码了,有兴趣的话可以阅读下filter的源码https://github.com/mozilla/nu…

January 15, 2019 · 1 min · jiezi