macro, nested, return

Page Contents

Synopsis

<#macro name param1 param2 ... paramN>
  ...
  <#nested loopvar1, loopvar2, ..., loopvarN>
  ...
  <#return>
  ...
</#macro>

Where:

The return and nested directives are optional and can be used anywhere and for any times between the <#macro ...> and </#macro>.

Parameters without default value must precede parameters with default value (paramName=defaultValue).

Description

Creates a macro variable (in the current namespace, if you know namespace feature). If you are new to macros and user-defined directives you should read the the tutorial about user-defined directives.

Macro variable stores a template fragment (called macro definition body) that can be used as user-defined directive. The variable also stores the name of allowed parameters to the user-defined directive. You must give value for all of those parameters when you use the variable as directive, except for parameters that has a default value. The default value will be used if and only if you don't give value for the parameter when you call the macro.

The variable will be created at the beginning of the template; it does not mater where the macro directive is placed in the template. Thus, this will work:

<#-- call the macro; the macro variable is already created: -->
<@test/>
...

<#-- create the macro variable: -->
<#macro test>
  Test text
</#macro>  

However, if the macro definitions are inserted with include directive, they will not be available until FreeMarker has executed the include directive.

Example: Macro without parameters:

<#macro test>
  Test text
</#macro>
<#-- call the macro: -->
<@test/>  

Output:

  Test text
   

Example: Macro with parameters:

<#macro test foo bar baaz>
  Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<#-- call the macro: -->
<@test foo="a" bar="b" baaz=5*5-2/>  

Output:

  Test text, and the params: a, b, 23
     

Example: Macro with parameters and default parameter values:

<#macro test foo bar="Bar" baaz=-1>
  Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<@test foo="a" bar="b" baaz=5*5-2/>
<@test foo="a" bar="b"/>
<@test foo="a" baaz=5*5-2/>
<@test foo="a"/>  

Output:

  Test text, and the params: a, b, 23
  Test text, and the params: a, b, -1
  Test text, and the params: a, Bar, 23
  Test text, and the params: a, Bar, -1
   

Example: A more complex macro.

<#macro list title items>
  <p>${title?cap_first}:
  <ul>
    <#list items as x>
      <li>${x?cap_first}
    </#list>
  </ul>
</#macro>
<@list items=["mouse", "elephant", "python"] title="Animals"/>  

Output:

  <p>Animals:
  <ul>
      <li>Mouse
      <li>Elephant
      <li>Python
  </ul>
   

Example: A macro with support for a variable number of named parameters:

<#macro img src extra...>
  <img src="/context${src?html}" 
  <#list extra?keys as attr>
    ${attr}="${extra[attr]?html}"
  </#list>
  >
</#macro>
<@img src="/images/test.png" width=100 height=50 alt="Test"/>  

Output:

  <img src="/context/images/test.png"
    alt="Test"
    height="50"
    width="100"
  >  

Example: A macro with that supports a variable number of positional parameters, regardless if it uses named or positional parameter passing:

<#macro m a b ext...>
  a = ${a}
  b = ${b}
  <#if ext?is_sequence>
    <#list ext as e>
      ${e_index} = ${e}
    </#list>
  <#else>
    <#list ext?keys as k>
      ${k} = ${ext[k]}
    </#list>
  </#if>
</#macro>

<@m 1 2 3 4 5 />

<@m a=1 b=2 c=3 d=4 e=5 data\-foo=6 myns\:bar=7 />  

Output:

  a = 1
  b = 2
      0 = 3
      1 = 4
      2 = 5

  a = 1
  b = 2
      c = 3
      d = 4
      e = 5
      data-foo=6
      myns:bar=7  

Warning!

Currently, named catch-all parameters are unordered, that is, you don't know what order will they be enumerated. That is, they aren't returned in the same order as they were passed in (that above example output shows them in the same order for understandability only).

nested

The nested directive executes the template fragment between the start-tag and end-tags of the user-defined directive. The nested part can contain anything what is valid in templates; interpolations, directives, ...etc. It is executed in the context where the macro was called from, rather than in the context of the macro definition body. Thus, for example, you don't see the local variables of the macro in the nested part. If you don't call the nested directive, the part between the start-tag and end-tags of the user-defined directive will be ignored.

Example:

<#macro do_twice>
  1. <#nested>
  2. <#nested>
</#macro>
<@do_twice>something</@do_twice>  

Output:

  1. something
  2. something
   

The nested directive can create loop variables for the nested content. For example:

<#macro do_thrice>
  <#nested 1>
  <#nested 2>
  <#nested 3>
</#macro>
<@do_thrice ; x>
  ${x} Anything.
</@do_thrice>  

This will print:

  1 Anything.
  2 Anything.
  3 Anything.
   

A more complex example:

<#macro repeat count>
  <#list 1..count as x>
    <#nested x, x/2, x==count>
  </#list>
</#macro>
<@repeat count=4 ; c, halfc, last>
  ${c}. ${halfc}<#if last> Last!</#if>
</@repeat>  

The output will be:

  1. 0.5
  2. 1
  3. 1.5
  4. 2 Last!
   

return

With the return directive, you can leave a macro or function definition body anywhere. Example:

<#macro test>
  Test text
  <#return>
  Will not be printed.
</#macro>
<@test/>  

Output:

  Test text
    
FreeMarker Manual -- For FreeMarker 2.3.22
HTML generated: 2015-02-28 21:34:03 GMT
Edited with XMLMind XML Editor
Here!