Как оценить параметр внутри макроса Freemarker?

Предположим, у нас есть простой макрос Freemarker:

<#macro myMacro expr>

    <#local x=1>
      ${expr}
    </#local>

    <#local x=2>
      ${expr}
    </#local>

</macro>

‹@myMacro "A"/> дает:

A A


Мне нужно что-то вроде ‹@myMacro "A${x}"/> должно дать:

A1 A2

но это не работает, так как ${x} интерполируется перед переходом в макрос. Это не работает, даже если я использую необработанную строку r"A${x}" в качестве параметра.

Пробовал играть с ?eval но результата пока нет(((

Можно ли сделать то, что мне нужно?


person wilddev    schedule 03.12.2011    source источник


Ответы (1)


Вы хотите оценить здесь выражение или фрагмент шаблона? Выражение похоже на 1 + 2 или "A${x}" (обратите внимание на кавычки; это строковый литерал), которое при передаче будет выглядеть как <@myMacro "1 + 2" /> и <@myMacro r'"A${x}"' />; последнее совсем неудобно. Фрагмент шаблона похож на <#list 1..x as i>${i}</#list> или A${x} (обратите внимание на отсутствие кавычек), что является более мощным и лучше выглядит внутри строки. Из того, что я вижу, вы, вероятно, хотите оценить фрагмент шаблона, поэтому он должен быть:

<#macro myMacro snippet>
  <#-- Pre-parse it for speed -->
  <#local snippet = snippet?interpret>

  <#local x = 1>
  <@snippet />

  <#local x = 2>
  <@snippet />
</#macro>

а затем вы можете использовать его как:

<@myMacro r"A${x}" />

или даже:

<@myMacro r"<ul><#list 1..x as i><li>${i}</li></#list><ul>" />

В любом случае, использование FreeMarker в целом немного странное, и если вы очень сильно полагаетесь на ?interpret или ?eval (например, вы делаете сотни таких операций для каждого HTTP-запроса), вы, возможно, сочтете его медленным. Медленно со стандартами Java, то есть.

person ddekany    schedule 03.12.2011
comment
Большое спасибо! Ваш метод с ?interpret меня устраивает! Мое использование freemarker довольно специфично, я использую его для генерации исходного кода, поэтому производительность ?interpret не так важна. - person wilddev; 04.12.2011