White-space handling

Page Contents

The control of the white-space in a template is a problem that to some extent haunts every template engine in the business.

Let see this template. I have marked the components of template with colors: text, interpolation, FTL tag. With the [BR]-s I visualize the line breaks.

<p>List of users:[BR]
<#assign users = [{"name":"Joe",        "hidden":false},[BR]
                  {"name":"James Bond", "hidden":true},[BR]
                  {"name":"Julia",      "hidden":false}]>[BR]
<ul>[BR]
<#list users as user>[BR]
  <#if !user.hidden>[BR]
  <li>${user.name}[BR]
  </#if>[BR]
</#list>[BR]
</ul>[BR]
<p>That's all.  

If FreeMarker were to output all text as is, the output would be:

<p>List of users:[BR]
[BR]
<ul>[BR]
[BR]
  [BR]
  <li>Joe[BR]
  [BR]
[BR]
  [BR]
[BR]
  [BR]  
  <li>Julia[BR]
  [BR]
[BR]
</ul>[BR]
<p>That's all.  

You have a lot of unwanted spaces and line breaks here. Fortunately neither HTML nor XML is typically white-space sensitive, but this amount of superfluous white-space can be annoying, and needlessly increases the size of produced HTML. Of course, it is even bigger problem when outputting white-space-sensitive formats.

FreeMarker provides the following tools to cope with this problem:

White-space stripping

If this feature is enabled for a template, then it automatically ignores (i.e. does not print to the output) two kind of typical superfluous white-space:

The output of the last example with white-space stripping enabled will be:

<p>List of users:[BR]
<ul>[BR]
  <li>Joe[BR]
  <li>Julia[BR]
</ul>[BR]
<p>That's all.  

This is because after stripping the template becomes the following; the ignored text is not colored:

<p>List of users:[BR]
<#assign users = [{"name":"Joe",        "hidden":false},[BR]
                  {"name":"James Bond", "hidden":true},[BR]
                  {"name":"Julia",      "hidden":false}]>[BR]
<ul>[BR]
<#list users as user>[BR]
  <#if !user.hidden>[BR]
  <li>${user.name}[BR]
  </#if>[BR]
</#list>[BR]
</ul>[BR]
<p>That's all.  

White-space stripping can be enabled/disabled in per template manner with the ftl directive. If you don't specify this with the ftl directive, then white-space stripping will be enabled or disabled depending on how the programmer has configured FreeMarker. The factory default is white-space stripping enabled, and the programmers probably left it so (recommended). Note that enabling white-space stripping does not degrade the performance of template execution; white-space stripping is done during template loading.

White-space stripping can be disabled for a single line with the nt directive (for No Trim).

Using compress directive

Another solution is to use the compress directive. As opposed to white-space stripping, this works directly on the generated output, not on the template. That is, it will investigate the printed output on the fly, and does not investigate the FTL program that creates the output. It aggressively removes indentations, empty lines and repeated spaces/tabs (for more information read the reference). So the output of:

<#compress>
<#assign users = [{"name":"Joe",        "hidden":false},
                  {"name":"James Bond", "hidden":true},
                  {"name":"Julia",      "hidden":false}]>
List of users:
<#list users as user>
  <#if !user.hidden>
  - ${user.name}
  </#if>
</#list>
That's all.
</#compress>  

will be:

List of users:
- Joe
- Julia
That's all.  

Note that compress is totally independent of white-space stripping. So it is possible that the white-space of template is stripped, and later the produced output is compress-ed.

Also, by default a user-defined directve called compress is available in the data-model (due to backward compatibility). This is the same as the directive, except that you may optionally set the single_line parameter, which will remove all intervening line breaks. If you replace <#compress>...</#compress> on the last example with <@compress single_line=true>...</@compress>, then you get this output:

List of users: - Joe - Julia That's all.  
FreeMarker Manual -- For FreeMarker 2.3.20
HTML generated: 2013-06-27 20:54:33 GMT
Edited with XMLMind XML Editor
Here!