freemaker 快速入门
此片入门是对官网上的一个简单的翻译,想要快速了解freemaker并进行开发的,这一篇足已!
一、简单介绍
在程序开发中,我们可能会频繁使用到一些类似的片段,例如,展示文本的table,由于table的样式基本一样,只有数据是不一样的,那我们可以考虑把这样一个具有相同样式的table做成一个模板。使用freemaker,可以简单快捷的实现这一设计。下面来看一个简单的freemaker的模板:
<html>
<head><title>Welcome!</title>
</head>
<body><h1>Welcome ${user}!</h1><p>Our latest product:<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>
这段模板和我们平时看到的静态的html页面一样,是存储在服务器上的,当用户访问的时候freemaker引擎能快速的把模板中的类似于${...}的内容替换成我们要展示的数据,最后展示给用户的是一个html页面,用户并不会知道我们服务器端用的是freemaker(当然我们的模板在替换之后并不会改变任何的内容,因为这个替换只发生在服务器响应的过程中)。即将要替换到模板的数据我们统称为data-model,这种数据是一个树形结构,就像我们的电脑上的文件夹和文件一样,可以被形象化这样:
(root)|+- animals| || +- mouse| | || | +- size = "small"| | || | +- price = 50| || +- elephant| | || | +- size = "large"| | || | +- price = 5000| || +- python| || +- size = "medium"| || +- price = 4999|+- message = "It is a test"|+- misc|+- foo = "Something"
这棵树通常会相对的复杂和深,可以看到这些数据就像目录一样,我们称为hashes,hashes 通常存储着其他的一些变量(如上面看到的animals,message,misc,foo等)。
对于只存储了单值的变量,如size,price等,我们称之为scalars。另外一种特殊的变量是sequences,sequence存储的子变量也像hashes一样,但是这些变量没有变量名,就像我们平时看到的数组一样。scalars储存的数据类型有:字符型、数组型、日期型、布尔型。
先来了解一点freemaker的基本语法
1、${...} 花括号内的内容将被替换成真实的值,我们称之为:interpolations
2、FTL标志 ftl的标志有点类似html,但是它们却是freemaker的指令语句,并不会被页面打印输出来,通常这些标志以#开头(用户自定义的标志使用@代替#,具有更高的优先级)、
3、注释 <#-- XXXXX -->
所有不是interpolations,ftl tag和注释的语句都会被freemaker认为是静态的文本,只做简单的输出而不会被freemaker引擎解释执行。
二、常用指令
1、The if directive
<#if animals.python.price != 0>Pythons are not free today!
</#if>
<#if animals.python.price < animals.elephant.price>Pythons are cheaper than elephants today.
<#else>Pythons are not cheaper than elephants today.
</#if>
<#if animals.python.price < animals.elephant.price>Pythons are cheaper than elephants today.
<#elseif animals.elephant.price < animals.python.price>Elephants are cheaper than pythons today.
<#else>Elephants and pythons cost the same today.
</#if>
2、The list directive
假设我们有这样的数据:
(root)|+- animals| || +- (1st)| | || | +- name = "mouse"| | || | +- size = "small"| | || | +- price = 50| || +- (2nd)| | || | +- name = "elephant"| | || | +- size = "large"| | || | +- price = 5000| || +- (3rd)| || +- name = "python"| || +- size = "medium"| || +- price = 4999|+- misc|+- fruits|+- (1st) = "orange"|+- (2nd) = "banana"
freemaker遍历list的模板如下:
<p>We have these animals:
<table border=1><#list animals as animal><tr><td>${animal.name}<td>${animal.price} Euros</#list>
</table>
将输出:
<p>We have these animals:
<table border=1><tr><td>mouse<td>50 Euros<tr><td>elephant<td>5000 Euros<tr><td>python<td>4999 Euros
</table>
我们需要注意这样一种情况:
<ul>
<#list misc.fruits as fruit><li>${fruit}
</#list>
</ul>
当misc.fruits就算是空的时候,程序仍然会输出<ul></ul>,因此我们建议这样写:
<#list misc.fruits><ul><#items as fruit><li>${fruit}</#items></ul>
</#list>
另外一种情景就是我们需要用一个分隔符来并列显示我们的数组,可以写成这样:
<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, </#list>
将输出:
<p>Fruits: orange, banana
我们用逗号来分割显示我们的数组,只有当数组后面还有其他元素时才会显示这个逗号,同样的,如果我们的数组中一个元素都没有的时候,页面上仍然会输出“Fruits:”,更好的写法应该是这样:
<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, <#else>None</#list>
上面说到的都是一些比较简单的使用方法,我们还可以写成这样:
<p>Fruits: ${fruits?join(", ", "None")}
当然我们可以把上面说到的几种指令用在一起:
<#list misc.fruits><p>Fruits:<ul><#items as fruit><li>${fruit}<#sep> and</#sep></#items></ul>
<#else><p>We have no fruits.
</#list>
3、The include directive
使用include指令能将其他文件的内容插入到前文件中。
假设我们需要把版权信息放在每一个页面的底部,我们可以将这个版权信息做成一个模板,命名成copyright_footer.html,如下:
<hr>
<i>
Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
<br>
All Rights Reserved.
</i>
然后每个需要添加版权信息的页面都include这个copyright_footer.html,如下:
<html>
<head><title>Test page</title>
</head>
<body><h1>Test page</h1><p>Blah blah...<#include "/copyright_footer.html">
</body>
</html>
最后页面输出:一旦修改了这个copyright_footer.html文件,所有引用的页面都能立即看到这些变化。
<html>
<head><title>Test page</title>
</head>
<body><h1>Test page</h1><p>Blah blah...
<hr>
<i>
Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
<br>
All Rights Reserved.
</i>
</body>
</html>
4、Using built-ins(使用內建函数)
- user?upper_case 把user值变成大写 (like "JOHN DOE" instead of "John Doe")
- user?cap_first 显示首字母大写user值 (like "Mouse" instead of "mouse")
- user?length 显示user的长度值 (8 for "John Doe")
- animals?size 显示animals sequence 的元素个数
- animal.protected?string("Y", "N") 根据animal.protected这个值是true还是false,返回Y或者N
- fruits?join(", ") 把一个list用逗号分隔显示成一串字符串
- user?starts_with("J") 如果user是以J开头返回true,否则返回false
- 如果我们是在<#list animals as animal>遍历中
- animal?index 获取是从0开始的索引值
- animal?counter 获取到的是从1开始的索引值
- animal?item_parity 根据当前元素的counter值返回是字符串“odd”或者“even”,一般用在改变奇偶行的颜色,像这样
<td class="${animal?item_parity}Row">
5、处理缺省值
data-model有些变量是可选的(有些是不小心missing,这里说的missing,是这可能没有这个变量,也可能是为null),为了识别出一些典型的人为错误,freemaker对一些缺少的变量值进行报错,除非人为的指定这个值可以为空,下面讲讲几个比较常用的方法:
1、当user值missing的时候,就会显示成visitor
<h1>Welcome ${user!"visitor"}!</h1>
2、当user值missing的时候,整行都不显示
<#if user??><h1>Welcome ${user}!</h1></#if>
我们需要注意这样一种情况,当我们要判断animals.python.price是不是等于0,我们通常会这样写:animals.python.price!0,但是如果animal或者Python已经missing,那么程序将报undefined variable的错误,为了避免这样的情况,我们建议写成这样:(animals.python.price)!0,这样,就算animal或者Python缺失,括号部分的值就会等于0,括号部分等同于(animals.python.price)??
6、Directives
前面提到,指令有预先系统定义的如<#if>,用户自己也可以定义自己的指令,用户自定义的指令和系统自带指令的不同之处就是,当用户级指令中没有需要嵌套的内容是,必须写成<@mydirective parameters />,就像我们html的img标签一样,而且用户自定义的指令具有更高的优先级。但是无论是系统级指令还是用户自定义指令,都必须要正确的嵌套,同时freemaker会忽略指令中大量的空格,所以你也可以写成这样,需要特别注意的是,并不允许在< 或者</和指令名之间插入空格。
<#list[BR]animals asanimal
>
${animal.name} for ${animal.price} Euros
</#list >
7、expresstion
声明:
1、字符串:"Foo" or 'Foo' or "It's \"quoted\"" or 'It\'s "quoted"' or r"C:\raw\string"
2、字符型:123.45
3、布尔值:true、false
4、序列sequence:["foo", "bar", 123.45]
5、hashes:{"name":"green mouse", "price":150}
取值:
1、顶层对象:user
2、从hashes中取值:user.name ,user["name"]
3、从sequence中取值:products[5]
4、特别变量:.main
字符串操作:
1、拼接:"Hello ${user}!" (or "Hello " + user + "!")
2、获取字符串的某一位上的字符值:name[0]
3、分割:包含最后一位:name[0..4],不包含最后一位:name[0..<5],去头:name[5..]
序列操作:
1、添加:users + ["guest"]
2、分割:包括最后一位products[20..29],不包括最后一位products[20..<30],去头products[20..]
hashes操作:
添加: passwords + { "joe": "secret42" }
算数计算:(x * 1.5 + 10) / 2 - y % 100
比较: x == y, x != y, x < y, x > y, x >= y, x <= y, x lt y, x lte y, x gt y, x gte y
逻辑运算:!registered && (firstVisit || fromEurope)
方法调用: repeat("What", 3)
缺值处理:
1、默认值:name!"unknown" or (user.name)!"unknown" or name! or (user.name)!
2、空值判断:name?? or (user.name)??
赋值运算符:=, +=, -=, *=, /=, %=, ++, --
转载于:https://www.cnblogs.com/baby-lijun/p/6674932.html
freemaker 快速入门相关推荐
- Shiro第一个程序:官方快速入门程序Qucickstart详解教程
目录 一.下载解压 二.第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三.shiro.ini分析 四.Quickstart. ...
- 计算机入门新人必学,异世修真人怎么玩?新手快速入门必备技巧
异世修真人怎么快速入门?最近新出来的一款文字修仙游戏,很多萌新不知道怎么玩?进小编给大家带来了游戏新手快速入门技巧攻略,希望可以帮到大家. 新手快速入门攻略 1.开局出来往下找婆婆,交互给点钱,旁边有 ...
- Spring Boot 2 快速教程:WebFlux 快速入门(二)
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘 ...
- Apache Hive 快速入门 (CentOS 7.3 + Hadoop-2.8 + Hive-2.1.1)
2019独角兽企业重金招聘Python工程师标准>>> 本文节选自<Netkiller Database 手札> 第 63 章 Apache Hive 目录 63.1. ...
- 《iOS9开发快速入门》——导读
本节书摘来自异步社区<iOS9开发快速入门>一书中的目录,作者 刘丽霞 , 邱晓华,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 前 言 第1章 iOS ...
- BIML 101 - ETL数据清洗 系列 - BIML 快速入门教程 - 序
BIML 101 - BIML 快速入门教程 做大数据的项目,最花时间的就是数据清洗. 没有一个相对可靠的数据,数据分析就是无木之舟,无水之源. 如果你已经进了ETL这个坑,而且预算有限,并且有大量的 ...
- python scrapy菜鸟教程_scrapy学习笔记(一)快速入门
安装Scrapy Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. pip install sc ...
- OpenStack快速入门
OpenStack云计算快速入门(1) 该教程基于Ubuntu12.04版,它将帮助读者建立起一份OpenStack最小化安装.我是五岳之巅,翻译中多采用意译法,所以个别词与原版有出入,请大家谅解.我 ...
- Expression Blend实例中文教程(2) - 界面快速入门
上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...
最新文章
- Git相关二三事(git reflog 和彩色branch)【转】
- ros::spinOnce()机制 有点东西
- 使用SQL脚本创建数据库,操作主键、外键与各种约束(MS SQL Server)
- OpenGL绘制带有索引的矩形的实例
- HALCON示例程序class_2dim_sup.hdev使用二维像素分类对图像进行分割
- uva 12563——Jin Ge Jin Qu hao
- BugkuCTF-MISC题可爱的故事
- javascript经典实例_一道前端经常忽视的JavaScript面试题
- 一篇图像识别的科普文
- linux date -s_Linux炫技:左手密码生成器,解放右手生产力
- 基于深度学习和模糊逻辑的葡萄黑麻疹疾病自动检测与严重程度分析(受控背景)
- Event Loop - JavaScript和node运行机制
- Android自带的抓包工具tcpdump
- 软件默认安装路径注册表更改问题
- OPENGL和DX的不同.
- 求大于200的最小质数
- JavaScript正则表达式分组模式:捕获性分组与非捕获性分组及前瞻后顾(断言)
- 关于孔明先生职称申请报告的回函
- 分享 60 个相见恨晚的神器工具
- 【深度之眼cs231n第七期】笔记(二十七)
热门文章
- Struts中DownloadAction的使用
- 力扣题目——53. 最大子序和
- Emgu.CV.CvInvoke的类型初始值设定项引发异常
- 64位win10系统无法安装.Net framework3.5的两种解决方法【转】
- 【异常(待解决)】org.apache.http.NoHttpResponseException: api.weixin.qq.com:443 failed to respond
- 如何使用Angular JS设置bootstrap navbar活动类?
- 用于检测浏览器语言偏好的JavaScript
- 在Objective-C中,如何测试对象类型?
- win10电脑ip地址怎么设置?几步就能学会
- 发送有序广播,只能运行在8.0之前的系统中