Создание своих макросов
Материал из DevelopmenOnTheEdge
								Версия от 13:55, 2 сентября 2014; Asko  (обсуждение | вклад)
Официальная документация по созданию макросов Freemarker здесь.
Особенности при переходе с m4:
- Все параметры макроса обязательны кроме тех, которым дано значение по умолчанию. Если раньше у макроса второй параметр был необязателен и писали так:
 
define(MY_MACRO, ... ifelse($2,,...))
теперь можно писать так:
<#macro MY_MACRO requiredParameter optionalParameter=''>... <#if optionalParameter==''>...<#else>...</#if>... </#macro>
- При вызове макроса можно именовать параметры для наглядности:
 
<@MY_MACRO requiredParameter='val1' optionalParameter='val2'/>
- Чтобы передать результат выполнения макроса в функцию (например, concat), надо присвоить этот результат в переменную с помощью <#assign>. Раньше писали:
 
_DBMS_CONCAT( MYMACRO1(arg1), MYMACRO2(arg2) )
Теперь так:
<#assign result1><@MYMACRO1 arg1/></#assign>
<#assign result2><@MYMACRO2 arg2/></#assign>
${concat(result1, result2)}
В некоторых случаях лучше определять не макрос, а функцию с помощью директивы <#function>. Тогда функцию можно будет использовать:
${concat( func1(arg1), func2(arg2) )
- Аргументы макроса не могут быть напрямую результатом выполнения другого макроса за исключением <#nested>-аргумента. Если у макроса один из аргументов предположительно может быть большим и нетривиальным или макрос по своей семантике его оборачивает, пользуйтесь <#nested>. Так сделан, например, предопределённый макрос <@bold/>:
 
<#macro bold>
  <#assign nested><#nested></#assign>
  ${concat('<b>'?str, nested, '</b>'?str)}
</#macro>
Пользоваться им в результате удобно и естественно:
<@bold><@italic>${concat('a', 'b')}</@></@>
-  Если макрос не имеет параметров вообще, возможно, стоит присвоить его значение переменной. Так вместо
 
<#macro USER_INFO>
User:
  ${concat('u.emailAddress', ' ('?str, 
    'per.courtesy', ' '?str, 
    'per.firstName', ' '?str, 
    'per.lastName', ', #'?str, 
    'per.ID'?asVarchar, ')'?str)}
</#macro>
Пишем:
<#assign USER_INFO>
User: 
  ${concat('u.emailAddress', ' ('?str, 
    'per.courtesy', ' '?str, 
    'per.firstName', ' '?str, 
    'per.lastName', ', #'?str, 
    'per.ID'?asVarchar, ')'?str)}
</#assign>
Тогда обращаться к USER_INFO можно в любом контексте по имени.