В этом году решил изменить вековые традиции и в Java проектах начать использовать вместо велосити (анг. Apache Velocity) популярный хипстерский мусташ (анг. Mustache). Дело в том, что в обычной жизни я, как правило, обхожусь вообще без шаблонизаторов и в простых случаях использую регулярки (regexp-ы). Когда нужно использовать сложные шаблоны для генерации текстовых файлов, то подключаю велосити (просто потому, что “рука набита”).
В этот раз нужно было что-то среднее. С одной стороны, не такое тяжеловесное, как велосити, а с другой стороны… не хотелось все делать руками. В итоге выбор пал на Mustache. В историческом обзоре на википедии написано, что изначально Mustache был сделан для рубистов. Тем не менее, позже он стал крайне популярен на фронтендэ у JavaScript-eров (и не только), и сейчас пользу от его использования сложно переоценить. Более того, если зайти на сайт Mustache, то можно узнать, что он реализован на 30+ языках программирования. Естественно Java также присутствует среди них. Если быть точным, то на сайте у них Java на десятом месте (между Objective-C и C#). Стоит отдать должное создателям java версии библиотеки. Хотя она занимает не первое место в списке, но находится, как и документация к ней, в весьма удовлетворительном состоянии. Установить библиотеку и начать с ней работу особого труда не составляет: jar-ик подключается через мавеновский репозиторий.
В качестве отличительных особенностей самого шаблонизатора можно указать следующие:
Во-первых, символами, обрамляющими метки-заполнители (placeholder-ы), являются фигурные скобки “{“. Визуально они чем-то напоминают усы (анг. mustache), повернутые на 90 градусов.
Выглядит это так:
Hello {{name}} You have just won {{value}} dollars! {{#in_ca}} Well, {{taxed_value}} dollars, after taxes. {{/in_ca}}
Во-вторых, основная идея mustache состоит в logic-less подходе. Под этим авторы подразумевают отсутствие различных if-else конструкций, а также циклов. Другими словами, вот такие велоситивские штуки не пройдут:
## Пример для Veloctity #if( $foo < 10 ) Go North #elseif( $foo == 10 ) Go East #elseif( $bar == 6 ) Go South #else Go West #end
Процессинг шаблонов в таком случае становится очень простым.
1. Берем шаблон.
2. Передаем данные. В случае Java это обычный Map.
3. Смотрим на ключ. Проверяем значение.
3.1. Значение является строчкой? Показываем.
3.2. Значение является пустым списком, false или отсутствует? Не показываем.
3.3. Значение является список (точнее Iterable)? Проходим по каждому элементу списка и применяем для него правило.
3.4. Значение является Callable? Получаем функциональщину.
С таким подходом можно решить большинство прикладных задач. Как я уже писал ранее, документация на сайте находится в нормальном состоянии и дает ответы на основные вопросы.
В ней детально изложены различные практические аспекты.
Например:
– Что делать, если вы хотите эскейптить HTML символы? Или не эскейпить?
– Что делать, если вы хотите выводить что-то в случае отсутствия данных (Inverted section)?
– Что делать, если вы хотите делать какую-то “предварительную” обработку данных, перед показом?
и т.д.
В-третьих. Сама структура библиотеки и ее архитектура оказались достаточно гибкими. Например, если есть желание хранить/загружать шаблоны из своего спецхранилища (а не только из файлов или загрузчиков классов), то можно сделать свою реализацию MustacheResolver. Другими словами, архитектура библиотеки более-менее сбалансированная. Не слишком много “абстракций”, но при этом сохранилась необходимая гибкость.