Создание своих макросов

Материал из DevelopmenOnTheEdge
Перейти к: навигация, поиск

Официальная документация по созданию макросов 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 можно в любом контексте по имени.