java - Email Internationalization using Velocity/FreeMarker Templates -
how can achieve i18n using templating engine such velocity or freemarker constructing email body?
typically people tend create templates like:
<h3>${message.hi} ${user.username}, ${message.welcome}</h3> <div> ${message.link}<a href="mailto:${user.emailaddress}">${user.emailaddress}</a>. </div>
and have resource bundle created properties like:
message.hi=hi message.welcome=welcome spring! message.link=click here send email.
this creates 1 basic problem: if .vm
files becomes large many lines of text, becomes tedious translate , manage each of them in separate resource bundle (.properties
) files.
what trying is, have separate .vm
file created each language, mytemplate_en_gb.vm, mytemplate_fr_fr.vm, mytemplate_de_de.vm
and somehow tell velocity/spring pick right 1 based on input locale.
is possible in spring? or should looking @ perhaps more simple , obvious alternative approaches?
note: have seen spring tutorial on how create email bodies using templating engines. doesn't seem answer question on i18n.
it turns out using 1 template , multiple language.properties files wins on having multiple templates.
this creates 1 basic problem: if .vm files becomes large many lines of text, becomes tedious translate , manage each of them in separate resource bundle (.properties) files.
it harder maintain if email structure duplicated on multiple .vm
files. also, 1 have re-invent fall-back mechanism of resource bundles. resource bundles try find nearest match given locale. example, if locale en_gb
, tries find below files in order, falling last 1 if none of them available.
- language_en_gb.properties
- language_en.properties
- language.properties
i post (in detail) had simplify reading resource bundles in velocity templates here.
accessing resource bundle in velocity template
spring configuration
<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>
i had create short-hand macro, msg
in order read message bundles. looks this:
#** * msg * * shorthand macro retrieve locale sensitive message language.properties *# #macro(msg $key) $messages.getmessage($key,null,$locale) #end #macro(msgargs $key, $args) $messages.getmessage($key,$args.toarray(),$locale) #end
resource bundle
email.hello=hello email.heading=this localised message email.message=your email id : {0} got updated in our system.
usage
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);
Comments
Post a Comment