You use FTL tags to call directives. In the example you have called the list directive. Syntactically you have done it with two tags: <#list animals as animal> and </#list>.

There are two kind of FTL tags:

  • Start-tag: <#directivename parameters>

  • End-tag: </#directivename>

This is similar to HTML or XML syntax, except that the tag name starts with #. If the directive doesn't have nested content (content between the start-tag and the end-tag), you must use the start-tag with no end-tag. For example you write <#if something>...</#if>, but just <#include something> as FreeMarker knows that the include directive can't have nested content.

The format of the parameters depends on the directivename.

In fact there are two types of directives: predefined directives and user-defined directives. For user-defined directives you use @ instead of #, for example <@mydirective parameters>...</@mydirective>. Further difference is that if the directive has no nested content, you must use a tag like <@mydirective parameters />, similarly as in XML (e.g. <img ... />). But user-defined directives is an advanced topic that will be discussed later.

FTL tags, like HTML tags, must be properly nested. So the code below is wrong, as the if directive is both inside and outside of the nested content of the list directive:

<#list animals as animal>
  <li>${} for ${animal.price} Euros
  <#if user == "Big Joe">
     (except for you)
</#list> <#-- WRONG! The "if" has to be closed first. -->

Note that FreeMarker doesn't care about the nesting of HTML tags, only about the nesting of FTL tags. It just sees HTML as flat text, it doesn't interpret it in any way.

If you try to use a non-existing directive (e.g., you mistype the directive name), FreeMarker will decline to use the template and produce an error message.

FreeMarker ignores superfluous white-space inside FTL tags. So you can write this:

  animals       as[BR]
${} for ${animal.price} Euros[BR]
</#list    >

You may not, however, insert white-space between the < or </ and the directive name.

The complete list and description of all directives can be found in the Template Language Reference/Directive Reference (but I recommend that you look at the chapter about expressions first).


FreeMarker can be configured to use [ and ] instead of < and > in the FTL tags and FTL comments, like [#if user == "Big Joe"]...[/#if]. For more information read: Miscellaneous/Alternative (square bracket) syntax.


FreeMarker can be configured so that it understands predefined directives without # (like <if user == "Big Joe">...</if>). However we don't recommend the usage of this mode. For more information read: Template Language Reference/Deprecated FTL constructs/Old FTL syntax