Pull to refresh

Вышло долгожданное обновление Velocity: шаблонить стало немного проще

Reading time4 min
Views7.5K

Обзор новых возможностей шаблонного движка


Первого декабря 2008 г. Apache объявила о выпуске новой версии давно не обновлявшегося шаблонного движка Velocity, за номером 1.6, а еще двумя неделями позже появился апдейт со свежими фиксами, Velocity Engine 1.6.1. Те, кто используют Velocity в своих проектах, будут рады узнать о новых возможностях, появившихся в новой версии. Те же, кто Velocity не используют, возможно, откроют для себя новый полезный инструмент.

Краткая справка


Apache Velocity — программный продукт, состоящий из ряда Java-библиотек. Продукт разрабатывается и поддерживается в рамках Apache Software Foundation, и распространяется как программное обеспечение с открытым кодом под лицензией Apache License 2.0. Главным компонентом продукта является Velocity Engine — библиотека, позволяющая формировать выходные тексты на основе шаблонов, что в просторечии именуется шаблонным движком.

Зачем нужны шаблонные движки


Вообще-то наиболее широкое применение шаблонные движки находят в веб разработке, но проще всего показать пользу от их использования на примере формирования текста письма. Допустим, у нас есть база пользователей, и мы хотим разослать анонс нового продукта. Текст стандартный, меняется только имя, дата и название продукта. Открываем блокнот и пишем:

Дорогой $customer.name

Компания "Рога и Копыта" с радостью доводит до Вашего сведения, что $product.name поступил в свободную продажу! Спрашивайте в аптеках города.

$date

Служба маркетинга компании "Рога и Копыта"


Как вы уже догадались, $customer.name, $product.name и $date — суть переменные, вместо которых при формировании выходного текста будут подставлены реальные значения. Возникает вопрос: как передать эти значения шаблону? Делается это очень просто. В исходнике Java прописываем:

VelocityEngine velocity = new VelocityEngine();
velocity.init();

Template letter = velocity.getTemplate("letter.vm");

Date now = new Date();
Product product = someDAO.getLatestProduct();
List<Customer> customers = someDAO.getCustomers();

for (Customer customer : customers) {
VelocityContext vc = new VelocityContext();
vc.put("customer", customer);
vc.put("product", product);
vc.put("date", now);

StringWriter sw = new StringWriter();
letter.merge(vc, sw);
// делаем с полученным текстом что хотим


Как видите, ничего особо мудреного тут нет: объекты Java, каждый под своим ключом, закладываются в экземпляр VelocityContext, который по сути представляет собой обычный Map. Когда в процессе слияния контекста с шаблоном движок встречает в тексте переменную, он использует ее имя в качестве ключа, и извлекает по нему из мапы соответствующий объект. Телемаркет!

Разумеется, нет никаких проблем приспособить шаблоны и для генерации HTML-страниц, что многие с успехом и сделали в свое время, выбросив на свалку истории во многом геморройную технологию JSP. Детальное описание языка шаблонов VTL и инструкцию по его использованию можно найти на сайте разработчика.

Но это все была предыстория. А теперь о собственно новой версии. На радость разработчикам, в 1.6 появился ряд долгожданных вкусностей. Рассмотрим их по порядку.

1. Директива #evaluate


Вот простой и жизненный пример: допустим, в базе хранится текст статьи. Где-то в середине мы хотим дать врезку с некими живыми данными: скажем, с результатами интернет-голосования. Это нетрудно: достаточно в нужном месте подключить файл шаблона, который выводит результаты в форме HTML:

#parse("poll.vm")

Беда, однако, в том, что если мы поместим текст статьи как обычную переменную ($article.text), ее содержимое тупо выведется на странице как есть. То есть вместо красивой диаграммы читатель увидит невразумительное #parse(«poll.vm»). Чтобы достичь нужного нам эффекта, нужно каким-то образом заставить Velocity интерпретировать текст статьи как код шаблона. Одной из немногих возможностей сделать это в прежних версиях было задействовать дополнительный компонент RenderTool из Velocity Toolbox. Что было, в принципе, терпимо, но несколько неудобно. С выходом 1.6 мы получили возможность делать это в одну строку:

#evaluate ($article.text)

2. Директива #define


Эта директива работает во многом подобно макросу, с той разницей, что куски шаблонного кода, определенные с его помощью, могут не только вызываться по месту, но и присваиваться контекстной переменной и далее использоваться там, где они окажутся нужны:

#define($block)Hello $who#end

#set($who = 'World!')

$block


Нужна ли нам такая конструкция на практике? Не так чтобы очень, но при ее наличии некоторые вещи можно реализовать более естественным способом. Например, что-нибудь типа шаблонного полиморфизма.

3. Директива #break


Мелочь, а приятно: теперь из цикла #foreach можно выскочить в одну строчку. При тех скудных средствах, которые имелись в Velocity для выражения логики управления, добавление целой новой директивы — уже огромный прорыв.

4. Возможность организовывать макросы в файлы


Одним из досадных ограничений старого Velocity было жестко фиксированное местоположение файла с макросами. Теперь макросы можно организовывать по своему усмотрению, и подключать их по мере необходимости:

#parse('mymacros.vm')

Вместо заключения


В этом обзоре были рассмотрены наиболее интересные новшества, появившиеся в Velocity Engine версии 1.6. Более подробно о новых возможностях движка можно прочитать на сайте продукта в разделе Changes.

Ну и резюмируя, не могу не отметить: «Жить стало лучше, жить стало веселей»!
Tags:
Hubs:
Total votes 32: ↑31 and ↓1+30
Comments12

Articles