1 assign 指令

使用这个指令你可以创建一个新的变量,或者替换一个已经存在的变量。注意仅仅顶级变量可以被创建/替换(也就是说你不能创建/替换some_hash.subvar,除了some_hash)。
关于变量的更多内

<#assign
seasons = ["winter", "spring", "summer", "autumn"]
test = test +
>

如果你知道什么是命名空间:assign指令在命名空间中创建变量。通常它在当前的命名空间(也就是和标签所在模板关联的命名空间)中创建变量。但如果你是用了in namespacehash,那么你可以用另外一个命名空间来创建/替换变量。比如,这里你在命名空间中/mylib.ftl创建/替换了变量bgColor。

<#import "/mylib.ftl" as my>
<#assign bgColor="red" in my>

assign的极端使用是当它捕捉它的开始标记和结束标记中间生成的输出时。也就是说,在标记之间打印的东西将不会在页面上显示,但是会存储在变量中。比如:

<#macro myMacro>foo</#macro>
<#assign x>
<#list .. as n>
${n} <@myMacro />
</#list>
</#assign>
Number of words: ${x?word_list?size}
${x}

输出结果为:

Number of words:
foo
foo
foo

请注意你不应该使用它来往字符串中插入变量:

<#assign x>Hello ${user}!</#assign> <#-- BAD PRACTICE! -->

上面是一种错误的写法

<#assign x="Hello ${user}!">

这种写法才是正确的

2 global 指令

这个指令和assign相似,但是被创建的变量在所有的命名空间中都可见,但又不会存在于任何一个命名空间之中。精确地说,正如你会创建(或替换)一个数据模型变量。因此,这个变量是全局的。如果在数据模型中,一个相同名称的变量存在的话,它会被使用这个指令创建的变量隐藏。如果在当前的命名空间中,一个相同名称的变量存在的话,那么会隐藏由global指令创建的变量。
比如<#global x = 1>,用创建了一个变量,那么在所有命名空间中x都可见,除非另外一个称为x的变量隐藏了它(比如你已经用<#assign x = 2>创建了一个变量)。这种情形下,你可以使用特殊变量globals,比如${.globals.x}。注意使用globals你看到所有全局可访问的变量;不但由global指令创建的变量,而且是数据模型中的变量。
自定义JSP标记的用户请注意:用这个指令创建的变量集合和JSP页面范围对应。这就意味着,如果自定义JSP标记想获得一个页面范围的属性(page-scope bean),在当前命名空间中一个相同名称的变量,从JSP标记的观点出发,将不会隐藏。

<#global name=value>
or
<#global name1=value1 name2=value2 ... nameN=valueN>
or
<#global name>
capture this
</#global>
这里: name:变量的名称。它不是表达式。但它可以被写作是字符串形式,如果变量名包含保留字符这是很有用的,比如<#global "foo-bar" = >。注意这个字符串没有扩展插值(如"${foo}")。
value:存储的值,是表达式。

3 t,lt,rt 指令

这些指令,指示FreeMarker去忽略标记中行的特定的空白
   t(整体削减):忽略本行中首和尾的所有空白。
   lt(左侧削减):忽略本行中首部所有的空白。
   rt(右侧削减):忽略本行中尾部所有的空白。
这里:
  “首部空白”表示本行所有空格和制表符(和其他根据UNICODE中的空白字符,除了换行符)在第一个非空白字符之前。
  “尾部空白”表示本行所有的空格和制表符(和其他根据UNICODE中的空白字符,除了换行符)在最后一个非空白字符之后,还有行末尾的换行符。
理解这些检查模板本身的指令是很重要的,而不是当你合并数据模型时,模板生成的输出。(也就是说,空白的移除发生在解析阶段)
比如这个

--
<#t>
<#t>
<#lt> <#rt>

输出结果为:

--

--
05-15 20:53