,先来一打小白兔;

3.1 总体结构

用程序语言编写的程序就是模板,模板也被成为FTL(代表FreeMarker模板语言)。

模板是由如下部分混合而成的:

  1. Text文本:文本会照着原样来输出;
  2. Interpolation插值:这部分的输出会被计算的值来代替。插值由${和}所分隔(或者#{和},这种风格已经不建议再使用了)。
  3. FTL tags标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示,而且不会打印在输出内容中。
  4. Comments注释:FTL的注释和HTML的注释也很相似,但是它们是由<#–和–>来分隔的。注释会被FreeMarker所忽略,更不会在输出内容中显示。

FTL区分大小写;

FTL标签不可以在其他FTL标签和插值中使用,下面这样写是错的;

<#if <#include 'foo'>='bar'>...</#if>

注释可以放在FTL标签和插值中间;

3.2 指令

标签分为两种:

  • 开始标签:<#directivename parametes>

  • 结束标签:

指令有两种类型:预定义指令和用户自定义指令。对于用户自定义的指令使用@来代替#;

3.3 表达式

3.3.1 简介

${expression}

3.3.2 快速浏览(备忘单)

这里是给已经了解FreeMarker的人或有经验的程序员的一个提醒:

3.3.3 直接确定值
3.3.3.1 字符串

转义

${"It's \"quoted\" and this is a blackslash: \\"}

输出:

It's "quoted" and this is a blackslash: \

转义序列表:

在1-4位的16进制码。下面这个示例中都是在字符串中放置版权符号“\xA9 1999-2001”,“\x0A9 1999-2001”,“\x00A9 1999-2001”;

一种特殊的字符串就是原生字符串。在原生字符串中,反斜杠和${没有特殊的含义,它们被视为普通的字符。为了表明字符串是原生字符串,在开始的引号或单引号之前放置字母r;

${r"${foo}"}
${r"C:\foo\bar"}

将会打印:

${foo}
C:\foo\bar
实例

<ul>
<li>转义:${"It's \"quoted\" and this is a blackslash: \\"}</li>
<li>版权符号:${"\xA9 1999-2000"}</li>
<li>原生字符串:${r"${foo}"}</li>
</ul>

输出:

3.3.3.2 数字

科学记数法暂不支持使用(1E3就是错误的)。不能在小数点之前不写0(.5也是错误的);

3.3.3.3 布尔值

直接写true或false就表示一个布尔值了;

3.3.3.4 序列

指定一个文字的序列,使用逗号来分隔其中的每个子变量,然后把整个列表放到方括号中。

<#list ["winter", "spring", "summer", "autumn"] as x>
${x}
</#list>

将会打印出:

winter
spring
summer
autumn

列表中的项目是表达式,那么也可以这样做:[2+2, [1,2,3,4], “whatnot”],其中第一个子变量是数字4,第二个子变量是一个序列,第三个子变量是字符串“whatnot”。

也可以用start..end定义存储数字范围的序列,这里start和end是处理数字值表达式,比如2..5和[2, 3, 4, 5]是相同的,但是使用前者会更有效率(内存占用少而且速度快)。可以看出前者也没有使用方括号,这样也可以用来定义递减的数字范围,比如5..2。(此外,还可以省略end,只需5..即可,到无穷大)。

实例

/FreeMarker-hello-web/src/main/webapp/WEB-INF/ftl/3/list.ftl


<#assign season=["summer", "winter", "spring", "autumn"]>
<p>
<#list season as s>
${s},
</#list>
</p>
<p>
<#list season[2..] as x>
${x},
</#list>
</p>

输出:

summer, winter, spring, autumn, 

spring, autumn, 
3.3.3.5 哈希表

键和值成对出现并以冒号分隔。{“name”:“green mouse”,“price”:150};

3.3.4 检索变量
3.3.4.1 顶层变量
3.3.4.2 从哈希表中检索数据

book.author.name来读取到auther的name;

如果我们想指定同一个表达式的子变量,那么还有另外一种语法格式:book[“title”]。

下面这些示例它们含义都是相等的:book.author.name, book["author"].name, book.author.["name"], book["author"]["name"]

当使用点式语法时,顶层变量名的命名也是相同的限制(命名时只能使用字母,数字,下划线,$,@等),而使用方括号语法形式时就没有这样的限制,它可以是任意的表达式。(为了FreeMarker支持XML,如果变量名是*(星号)或者**,那么就应该使用方括号语法格式)。

3.3.4.3 从序列中检索数据

animals[0].name

3.3.4.4 特殊变量

特殊变量是由FreeMarker引擎本身定义的,为了使用它们,可以按照如下语法形式来进行:.variable_name;

3.3.5 字符串操作
3.3.5.1 插值(或连接)
3.3.5.2 获取一个字符

user[0],假设user是”Big Joe“,那么

${user[0]}
${user[4]}

将会打印:

B
J

可以使用切分序列的方式来获取一定范围内的字符,比如user[1..4]{user[4..]},然而这种使用方法已经被废弃了,作为它的替代,可以使用内建函数substring。

实例

/FreeMarker-hello-web/src/main/webapp/WEB-INF/ftl/3/string.ftl


<ul>
<li>读取一个字符:${user[0]}</li>
<li>读取一定范围的字符:${user[1..5]}</li>
<li>这种操作已经废弃了,现在使用内建函数substring,${user?substring(1, 5)}</li>
</ul>

输出:

•读取一个字符:B
•读取一定范围的字符:ig Jo
•这种操作已经废弃了,现在使用内建函数substring,ig J
3.3.6 序列操作
3.3.6.1 连接

序列的连接可以使用+号来进行:

<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
\- ${user}
</#list>

要注意不要在很多重复连接时使用序列连接操作,比如在循环中往序列上追加项目,通过这种方式进行的许多重复连接最终产生的序列读取的速度会变慢;

3.3.6.2 序列切分

使用[firstindex..lastindex]可以获取序列中的一部分,这里的firstindex和lastindex表达式的结果是数字,如果seq存储序列“a”,“b”,“c”,“d”,“f”,那么表达式seq[1..4]将会是含有“b”,“c”,“d”,“e”的序列。

实例

/FreeMarker-hello-web/src/main/webapp/WEB-INF/ftl/3/list.ftl


<h3>序列的操作</h3>
<ul>
<li>+连接:
<#list ["sumer", "winter"]+["spring", "autumn"] as x>
${x}.
</#list>
</li>
<li>序列切分:
<#list season[2..3] as x>
${x},
</#list>
</li>
</ul>
3.3.7 哈希表操作
3.3.7.1 连接

可以使用+号连接哈希表

<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
3.3.8 算数运算

求模(求余): %

3.3.9 比较运算

测试两个值相等使用=(或者==,二者是完全等同的)

3.3.10 逻辑操作
3.3.11 内建函数

内建函数以?形式提供变量的不同形式或者其他信息。

例如得到字符串的大写形式:user?upper_case;

字符串使用的内建函数:

  • html:字符串中所有的特殊HTML字符都需要用实体引用来代替(比如<代替<)。

  • cap_first:字符串的第一个字母变为大写形式;
  • lower_case:字符串的小写形式;
  • upper_case:字符串的大写形式;
  • trim:去掉字符串首尾的空格;

序列使用的内建函数:

  • size:序列中的元素的个数

数字使用的内建函数:

  • int:数字的整数部分(比如-1.9?int就是-1)

示例:

${test?html}
${test?upper_case?html}

输出是:

Tom &amp; Jerry
TOM &amp; JERRY
3.3.12 方法调用

假设程序员定义了一个可供调用的方法repeat。第一个参数字符串类型,第二个参数是数值类型。

${repeat("What", 3)}

打印出:

WhatWhatWhat
3.3.13 处理不存在的值

要注意这个操作是FreeMarker2.3.7版本以后才有的(用来代替内建函数default,exists和if_exists);

3.3.13.1 默认值

unsafe_expr!default_expr或 unsafe_expr! 或 (unsafe_expr)!default_expr 或 (unsafe_expr)!

${mouse!"No mouse."}
<#assign mouse="Jerry">
${mouse!"No mouse."}

将会输出:

No mouse.
Jerry

默认值可以是任何类型的表达式,也可以不必是字符串。

hits!0;
colors!["red", "green", "blue"]

默认值表达式的复杂程序没有严格限制,你可以这么来写:

cargo.weight!(item.weight * itemCount+10)

如果默认值被忽略了,那么结果将会是空串,空序列或空哈希表。

(${mouse!})
<#assign mouse = "Jerry">
(${mouse!})

输出为:

()
(Jerry)

在不是顶层变量时,默认的操作符可以有两种方式:

product.color!"red"

当color不存在时(返回“red”)将会被处理,但是如果连product都不存在时将不会处理,也就是说这种写法product必须存在,否则模板就会报错。

(product.color)!"red"

这种写法,如果product不存在或者product存在而color不存在,都能显示默认值“red”而不会报错。

默认值操作也可以作用于序列,比如:

<#assign seq = ['a', 'b']>
${seq[0]!'-'}
${seq[1]!'-'}
${seq[2]!'-'}
${seq[3]!'-'}

输出为:

a
b
\-
\-
3.3.13.2 检测不存在的值

unsafe_expr??或者(unsafe_expr)??

<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>
Creating mouse...
<#assign mouse = "Jerry">
<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>

输出为:

No mouse found
Creating mouse...
Mouse found
3.3.14 括号
3.3.15 表达式中的空格

FTL忽略表达式中的多余空格。

3.3.16 操作符的优先级

3.4 插值

项目

  1. P1:https://github.com/yejq/FreeMarker-hello-java.git

  2. P2:https://github.com/yejq/FreeMarker-hello-web.git

FreeMarker笔记 第三章 模板的更多相关文章

  1. Android群英传笔记——第三章:Android控件架构与自定义控件讲解

    Android群英传笔记--第三章:Android控件架构与自定义控件讲解 真的很久没有更新博客了,三四天了吧,搬家干嘛的,心累,事件又很紧,抽时间把第三章大致的看完了,当然,我还是有一点View的基 ...

  2. spring boot 笔记--第三章

    spring boot 笔记 第三章,使用Spring boot 构建系统: 强烈建议支持依赖管理的构建系统,Maven或Gradle 依赖管理: Spring Boot的每版本都会提供它支持的依赖列 ...

  3. The Road to learn React书籍学习笔记(第三章)

    The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...

  4. 《DOM Scripting》学习笔记-——第三章 DOM

    <Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...

  5. 《Linux内核设计与分析》第六周读书笔记——第三章

    <Linux内核设计与实现>第六周读书笔记——第三章 20135301张忻估算学习时间:共2.5小时读书:2.0代码:0作业:0博客:0.5实际学习时间:共3.0小时读书:2.0代码:0作 ...

  6. [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设

    [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...

  7. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

  8. python学习笔记——第三章 串

    第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...

  9. C++ Primer 笔记 第三章

    C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...

随机推荐

  1. 【原创】Android 4.4前后版本读取图库图片方式的变化

    Android 4.4前后版本读取图库图片方式的变化   本文讲述Android 4.4(KitKat)前后访问图库以及访问后通过图片路径读取图片的变化   Android 4.4(KitKat)以前 ...

  2. Highcharts属性详解

    Highcharts的基本属性和方法详解 Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学 ...

  3. Android 防止按钮连续点击的方法(Button,ImageButton等)

    防止按钮连续点击  其实实现很简单 共通方法 public class Utils { private static long lastClickTime; public static boolean ...

  4. 整合Struts2+SiteMesh+Spring+MyFaces(JSF)+Freemarker的时候启动服务器报错ClassNotFoundException: org.apache.struts2.sitemesh.FreeMarkerPageFilter

    我一琢磨,难道freemarker与struts2的整合也需要添加一个struts2-freemarker-plugin的jar包? 后来找了半天,确认不需要这个. 然后我就上网搜,这个FreeMar ...

  5. 《c程序设计语言》读书笔记--每行一个单词打印输入的字符,除去空符

    #include <stdio.h> int main() { int c; while((c = getchar()) != EOF) { if(c != '\n' && ...

  6. python3代码

    import urllib.request url="http://mm.taobao.com/json/request_top_list.htm?type=0&page=1&quo ...

  7. js收藏

    //设为主页function SetHome(obj, vrl) { try { obj.style.behavior = 'url(#default#homepage)'; obj.setHomeP ...

  8. 概述hibernate入门安装配置

    1.jdbc连接的优缺点 JDBC的优点 直接底层操作,提供了很简单.便捷的访问数据库的方法,跨平台性比较强.灵活性比较强,可以写很复杂的SQL语句. JDBC的缺点 1).因为JAVA是面向对象的, ...

  9. SQL注入与Java

    前面这篇文章介绍了SQL注入,并且主要就PHP的内容做了实验: http://www.cnblogs.com/charlesblc/p/5987951.html 还有这篇文章对处理方案做了介绍(Pre ...

  10. 图片缓存之内存缓存技术LruCache,软引用

    每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常, 这个问题曾经让我觉得很烦恼,后来终于得到了解决, 那么现在就让我和大家一起分享一下吧. 这篇博文要讲的图片缓存机制,我接触到的有两 ...