首页 > 代码库 > freemarker 空白处理

freemarker 空白处理

1 简介

HTML 和 XML 都不是对空白敏感的,但是这么多多余的空白是很令人头疼的,而且增加处理后的 HTML 文件大小也是没必要的。当然,对于空白敏感的方式的输出这依旧是个大问题。

FreeMarker 提供下面的工具来处理这个问题:

  • 忽略某些模板文件的空白的工具(解析阶段空白就被移除了):
    • 剥离空白:这个特性会自动忽略在 FTL 标签周围多余的空白。这个特性可以通过模板来随时使用和禁用。
    • 微调指令: t , rt 和 lt ,使用这些指令可以明确地告诉 FreeMarker 去忽略某些空白。可以阅读参考手册来获取更多信息。
    • FTL 参数 strip_text :这将从模板中删除所有顶级文本。对模板来说这很有用,它只包含某些定义的宏(还有以他一些没有输出的指令),因为它可以移除宏定义和其他顶级指令中的换行符,这样可以提高模板的可读性。
  • 从输出中移除空白的工具(移除临近的空白):
    • compress 指令

2 剥离空白
如果对于模板来说使这个特性成为可能的话,那么它就会自动忽略(也就是不在输出中打印出来)两种典型的多余空白:
  • 缩进空白和在行末尾的尾部空白(包括换行符)将会被忽略,只会留下 FTL 标签(比如 <@myMacro/> , <#if ...> )和 FTL 注释(如 <#-- blah --> ),除了被忽略的空白本身。例如,如果一行只包含一个 <#if ...> ,那么在标签前面的缩进和标签后面的换行符将会被忽略。然而,如果这行上包含 <#if ...>x ,那么空白就不会被忽略,因为这个 x 不是 FTL 标签。注意,根据这些规则,一行上 包 含 <#if ...><#list ...> , 空 白 就 会 被 忽 略 , 而 一 行 上 有<#if ...> <#list ...> 这样的就不会,因为在两个 FTL 标签之间的空白
    是嵌入的空白,而不是缩进的或尾部空白。
  • 加在下面这些指令之间的空白会被忽略: macro , function , assign ,global , local , ftl , import ,但也是仅仅指令之间只有一个空白或 FTL注释。实际应用中,它意味着你可以在宏定义和参数定义之间放置空行,因为行间距是为了更好的可读性,不包括打印不必要的空行(换行符)。

默认的情况下剥离空白是开启的,程序员可以留着不管( 建议这样做 )。 注意开启剥离空白时不会降低模板执行的效率,剥离空白的操作在模板加载时就已经完成了。
剥离空白可以为单独的一行关闭,就是使用 nt 指令(对没有去掉空白的行来说)。

3 使用 compress 指令
另外一种方法就是使用 compress 指令,和剥离空白相反,这个工作是直接基于生成的输出内容,而不是对于模板进行。也就是说,它会动态地检查输出内容,而不会检查生成输出 FTL 的程序。它会很强势地移除缩进,空行和重复的空格/制表符(可以阅读参考手册部分来获取更多信息)。所以对于下面这段代码:
<#compress>
<#assign users = [{"name":"Joe","hidden":false},
<span style="white-space:pre">		</span>{"name":"James Bond", "hidden":true},
<span style="white-space:pre">		</span>{"name":"Julia","hidden":false}]>
List of users:
<#list users as user>
  <#if !user.hidden>
  - ${user.name}
  </#if>
</#list>
That's all.
</#compress>
List of users:
- Joe
- Julia
That's all.

在默认情况下,名为 compress 的用户自定义指令是可以在数据模型中存在的(由于向下兼容特性)。这和指令是相同的,除了可以选择设置 single_line 属性,这将 会 移 除 所 有 的介 于 其 中的 换 行 符 。在 最 后 那 个例 子 中 , 如果 使 用 <@compress
single_line=true>...</@compress>来代替<#compress>...</#compress> ,那么就会得到如下输出:
List of users: - Joe - Julia That's all.