Freemarker

FreeMarker 是一款模板引擎:即一种基于模板、用来生成输出文本(任何来自于 HTML 格式的文本用来自动生成源代码)的通用工具。

一句话概括

模板和数据模型是 FreeMarker 所需,并用来生成输出内容的(比如之前展 示的 HTML): 模板+数据模型=输出

数据模型(data-model)

数据模型可以被看做是树状结构的。 包括:

  • 标量 存储单一的值,这种类型的值可以是字符串,数字,日期/时间或者是布尔值。

  • 哈希表 是存储变量和与其相关且有唯一标识名称变量的容器。

  • 序列 是存储有序变量的容器。存储的变量可以通过数字索引来检索,索引通常从零开始。

模板

  • ${...}: FreeMarker 将会输出真实的值来替换花括号内的表达式,这样的表达式被称为 interpolations 插值,可以参考第上面示例的内容。

  • FTL tags 标签(FreeMarker 模板的语言标签): FTL 标签和 HTML 标签有一点相似,但是 它们是 FreeMarker 的指令而且是不会直接输出出来的东西。这些标签的使用一般以符号# 开头。(用户自定义的 FTL 标签使用@符号来代替#,但这是更高级的主题内容了,后面会详细地讨论)

  • Comments 注释: FreeMarker 的注释和 HTML 的注释相似,但是它用<#--和-->来分 隔的。任何介于这两个分隔符(包含分隔符本身)之间内容会被 FreeMarker 忽略,就不会 输出出来了。 其他任何不是 FTL 标签,插值或注释的内容将被视为静态文本,这些东西就不会被 FreeMarker 所解析,会被按照原样输出出来。

  • directives 指令: 就是所指的 FTL 标签。这些指令在 HTML 的标签(如和
    )和 HTML 元素(如 table 元素)中的关系是相同的。(如果现在你还不能区 分它们,那么把“FTL 标签”和“指令”看做是同义词即可。)

插值

插值表达式的结果必须是字符串,数字或日期类型的,因为只有数字和日期类型可以自 动转换为字符串类型,其他类型的值(如布尔,序列)只能手动转换为字符串类型,否则就 会发生错误导致模板执行中止。

内建函数

内建函数以 ?形式提供变量的不同形式 或者其他信息。 如${'abc'?substring(0)}

简单举例: 字符串使用的内建函数:

  • html: 字符串中所有的特殊 HTML 字符都需要用实体引用来代替(比如<代替<)。
  • cap_first:字符串的第一个字母变为大写形式
  • lower_case:字符串的小写形式
  • upper_case:字符串的大写形式
  • trim:去掉字符串首尾的空格

序列使用的内建函数:

  • size:序列中元素的个数

数字使用的内建函数:

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

指令和FTL标签的关系

使用FTL标签来调用directives指令

指令

指令有两种类型:预定义指令和用户自定义指令。

对于用户自定义的指令使用 @来代替#,比如<@mydirective parameters>.../@mydirective

预定义指令介绍

   * if指令:

    <#if true>
        输出
    <#else>
       不输出
    </#if>


   * list指令

    <#list sequence as loopVariable>
        <h1>loopVariable.title</h1>
        <p>loopVariable.desc</p>
    </#list> 


   * include指令

    <#include "/a.html">

自定义指令

自定义指令可以使用 macro 指令来定义,这是模板设计者所关心的内容。

宏是有一个变量名的模板片段。你可以在模板中使用宏作为自定义指令,这样就能进行重复性的工作。

  • 定义宏

    person是参数,greet是宏的名字

    <#macro greet person]]> <font size="+2">Hello ${person}!</font> </#macro>

  • 使用宏

    <@greet person="Fred"/> and <@greet person="Batman"/> 使用自定义的指令,用@,而使用预定义的指令,用#

  • 进阶

    嵌套内容,<#nested>

  • 在模板中定义变量

  • 简单变量:它能从模板中的任何位置来访问,或者从使用 include 指令引入的 模板访问。可以使用 assign 或 macro 指令来创建或替换这些变量。

  • 局部变量:它们只能被设置在宏定义体内,而且只在宏内可见。一个局部变量的生 存周期只是宏的调用过程。可以使用 local 指令在宏定义体内创建或替换局部变量。
  • 循环变量:循环变量是由指令(如 list)自动创建的,而且它们只在指令的开始 和结束标记内有效。宏的参数是局部变量而不是循环变量。

警告 一个常犯的错误是在不能使用插值的地方使用了它。 典型的错误就是<#if ${isBig}>Wow!</#if>,这是语法上的错误。只要写为<#if isBig>Wow!</#if> 就对了,而且<#if "${isBig}">Wow!</#if>也是错误的,因为这样参数就是字符 串类型了,但是 if 指令的参数要求是布尔值,所以运行时就会发生错误。

提醒——处理不存在的变量

对于不存在的或为null的变量,freemarker认为都是一种“变量丢失”,除非你指定该情况下的处理,否则,模板会忽略。

如果希望变量丢失(不存在)时输出xxx,<h1>Welcome ${user!"Anonymous"}!</h1>如过user不存在,则输出Anonymous 如果想根据变量存在情况来判断,可结合if指令,<#if user??><h1>Welcome ${user}!</h1></#if>

小点

  • 三目运算符 (a == '123') ? string("123" , "456")

results matching ""

    No results matching ""