Создание своих макросов
Материал из 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 можно в любом контексте по имени.