Комментарии 16
Так и есть. Initial Release — в 2000 (https://en.wikipedia.org/wiki/Apache_FreeMarker).
Также, насколько я помню, разработчики старались не иметь сторонних библиотек в зависимостях (что большой плюс при энтерпрайзной некрокодоархеологии).
Можно, а как же!
Пишем шаблон (это весь шаблон): ${reactApp}
Запускаем рендеринг реакт-приложения в отдельном потоке, собираем его stdout
Кладем собранный stdout в HashMap как в примерах и рендерим шаблон.
Профит!
собственно мы сейчас им (velocity) и пользуемся, и для проснения функциональности — пара вопросов, если можно:
* можно ли в free maker отправлять на рендеринг шаблоны, созданные динамически в рантайме? например в jsf такой фичи нет — все шаблоны компиляются во время сборки. а с velocity я так могу.
* если в значение строки подставить html — оно отрендерится как html или будет экранированно?
* есть возможность условного рендеринга? т.е. если значение переменной такое — то рендерим этот кусок, если нет то другой? мы часто этим пользуемся, перекладывая часть логики построения на плечи шаблонизатора.
* есть возможность реализовать внутри шаблона цикл? или list — это единственная «расширенная фича»?
* есть ли возможность обращаться к bean-свойствам объекта который погружен в контекст? т.е. я в хешмапе определяю одну переменную, а потом пользуюсь всеми его методами и свойствами, без необходимости в хешмапе определять 20+ значений.
Спасибо.
По поводу динамических шаблонов — вообще не проблема. У нас шаблоны хранятся в базе (+кеш) и чудненько в процессе работы перегенерируются. Причем используются именно html, т.е. с экранированием тоже проблем нет. Соответственно вообще можно построить логику, что будет по нужным звездам разные шаблоны подаваться, делая ветвление в java логике или же if-ами.
С бинами проблем тоже нет. Через точку можно обращаться к свойства любой глубины вложенности. Там есть реализация бин обработчика (BeansWrapperBuilder), Map-у мы вообще не используем
Плюс в спринге поддержка velocity теперь deprecated и рекомендуют переезд на freemarker
тайпхинты? рад что вам нравится, но для нас это не не аргумент — идеей не пользуемся и в здравом уме и твердой памяти ее закупать в масштабах предприятия никто не будет; есть еще к ней личные претензии по поводу невозможности отобразить структуру анонимных классов в навигаторе по структуре кода, но… отложим. это вообще не по теме сейчас)
работа с мапами удобнее? давайте чуть позже обсудим.
сначала конкретику: как в freemarker сделать вот такие вещи?
пример 1
##пример шаблона apache velocity
#if ( $var == "zz")
<div>zzzz</div>
#else
<b>xxxx</b>
#end
пример 2
##пример шаблона apache velocity
#foreach ($var in $obj.mycollect)
##getDescription - это функция в бине obj
#set ($dVar = $obj.getDescription($var))
##value - это bean - свойство с геттером
<div>${var.value} ( $dVar )</div>
#end
<#assign x = «plain»> — create variable x
<#if ${x} == 1>
zzzz
<#else>
xxxx
</#if>
2. второй пример делаем через лист, вызовы методов бина, делаем на момент формирования модели, и сохраняем в полях объекта, так думаю даже лучше в плане поиска ошибок и отладки, А так есть локальные, глобальные переменные шаблонов, условия и пр.
Вообще не сторонник доказывать что именно этот Фреймворк лучше, хуже, все имеют право быть под Солнцем, есть критерии выбора для проекта, предприятия и пр. Главное чтобы решал поставленные задачи, был эффективным, ну и приятным в использовании и разработке.
<#list mycollect as item>
</#list>
исходя из описания по пункту 2:
1) верно ли я понимаю, что во freemarker нет переменных, которые вы можете создавать в самом шаблоне?
2) есть ли вызов паблик-функций класса? (вызов bean-свойств есть, но это несколько другое)
локальные в рамках шаблона <#local name=value>
глобальные, доступные во всех шаблонах <#global name=value>
2. Как вариант можно так:
делаем класс
public class JavaCall implements TemplateMethodModel {
@Override
public Object exec(List args) throws TemplateModelException {
return "Hello " + (String) args.get(0);
}
}
//
подготавливаем в модели вызов метода
root.put("javaHello", new JavaCall());
//
в шаблоне ftl вызываем
${javaHello("FreeMatker")}
— Если в значение переменной поставить html, он так и выведется
— Условный рендеринг
<#if condition>
…
<#elseif condition2>
…
<#elseif condition3>
— В основном list, внутри уже можно if, break, continue
— Можно,
Map root = new HashMap();
Product latest = new Product();
latest.setUrl(«products/greenmouse.html»);
latest.setName(«green mouse»);
root.put(«latestProduct», latest);
Ftl
a href="${latestProduct.url}">${latestProduct.name}
попадалась презенташка, в которой был кусочек сравнения https://www.slideshare.net/alexeymigutsky/jsp-thymeleaf-20
FreeMarker шаблоны