Оказывается, использование одного шаблона и нескольких файлов language.properties выигрывает при наличии нескольких шаблонов.
Это создает одну основную проблему: если мои файлы .vm становятся большими с большим количеством строк текста, онистановится утомительным переводить и управлять каждым из них в отдельных файлах комплекта ресурсов (.properties).
Еще сложнее поддерживать, если ваша структура электронной почты дублируется в нескольких .vm
файлах.Кроме того, нужно будет заново изобрести запасной механизм комплектов ресурсов.Ресурсные связки пытаются найти ближайшее совпадение с учетом локали.Например, если языковой стандарт en_GB
, он пытается найти указанные ниже файлы по порядку, возвращаясь к последнему, если ни один из них не доступен.
- language_en_GB.properties
- language_en.properties
- language.properties
Я опубликую (подробно), что мне нужно было сделать, чтобы упростить чтение пакетов ресурсов в шаблонах Velocity.
Доступ к пакету ресурсов в шаблоне Velocity
Конфигурация Spring
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="content/language" />
</bean>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="resourceLoaderPath" value="/WEB-INF/template/" />
<property name="velocityProperties">
<map>
<entry key="velocimacro.library" value="/path/to/macro.vm" />
</map>
</property>
</bean>
<bean id="templateHelper" class="com.foo.template.TemplateHelper">
<property name="velocityEngine" ref="velocityEngine" />
<property name="messageSource" ref="messageSource" />
</bean>
TemplateHelper Class
public class TemplateHelper {
private static final XLogger logger = XLoggerFactory.getXLogger(TemplateHelper.class);
private MessageSource messageSource;
private VelocityEngine velocityEngine;
public String merge(String templateLocation, Map<String, Object> data, Locale locale) {
logger.entry(templateLocation, data, locale);
if (data == null) {
data = new HashMap<String, Object>();
}
if (!data.containsKey("messages")) {
data.put("messages", this.messageSource);
}
if (!data.containsKey("locale")) {
data.put("locale", locale);
}
String text =
VelocityEngineUtils.mergeTemplateIntoString(this.velocityEngine,
templateLocation, data);
logger.exit(text);
return text;
}
}
Velocity Template
#parse("init.vm")
#msg("email.hello") ${user} / $user,
#msgArgs("email.message", [${emailId}]).
<h1>#msg("email.heading")</h1>
Мне пришлось создать сокращенный макрос, msg
, чтобы читать из пакетов сообщений.Выглядит это так:
#**
* msg
*
* Shorthand macro to retrieve locale sensitive message from language.properties
*#
#macro(msg $key)
$messages.getMessage($key,null,$locale)
#end
#macro(msgArgs $key, $args)
$messages.getMessage($key,$args.toArray(),$locale)
#end
Комплект ресурсов
email.hello=Hello
email.heading=This is a localised message
email.message=your email id : {0} got updated in our system.
Использование
Map<String, Object> data = new HashMap<String, Object>();
data.put("user", "Adarsh");
data.put("emailId", "adarsh@email.com");
String body = templateHelper.merge("send-email.vm", data, locale);