Reputation: 47
I am using Pebble
to process mail content, and it works great,
usually I make it getting locale from environment variables:
@Autowired
private Environment env;
PebbleTemplate template = pebbleEngine.getTemplate(templateName);
Writer writer = new StringWriter();
template.evaluate(writer, templateVars, Locale.forLanguageTag(env.getProperty("system-prop.locale")));
String content = writer.toString();
<td>
{{ i18n("messages/mail", "welcome.words") }}
</td>
Now I've got some extraordinary templates that I would like to put both English and French messages at the same time,
does Pebble
provides any methods to manually designate locale like Handlebars.java
?
<td>
{{i18n "welcome.words" locale="en_US"}}<br />
{{i18n "welcome.words" locale="fr_FR"}}
</td>
Upvotes: 0
Views: 516
Reputation: 47
Thanks to answer from @eric-bussieres,
I came up with the custom function which is a modified version of i18n.
Output:
<td>
Hello World
Bonjour World
</td>
Codes:
<!-- paragraph.html -->
<td>
{{ i18ncustom("messages/mail", "welcome.words", "en_US", name) }}<br />
{{ i18ncustom("messages/mail", "welcome.words", "fr_FR", name) }}
</td>
#mail_en_US.properties
welcome.words=Hello {0}
#mail_fr_FR.properties
welcome.words=Bonjour {0}
@Autowired
private PebbleEngine pebbleEngine;
public void test() throws IOException {
PebbleTemplate template = pebbleEngine.getTemplate("paragraph");
Writer writer = new StringWriter();
template.evaluate(writer, Collections.singletonMap("name", "World"));
log.info("{}", writer.toString());
}
@Configuration
public class PebbleConfig {
@Bean
public Extension i18nCustomExtension() {
return new I18nCustomExtension();
}
}
public class I18nCustomExtension extends AbstractExtension {
@Override
public Map<String, Function> getFunctions() {
Map<String, Function> functions = new HashMap<>();
functions.put("i18ncustom", new I18nCustomFunction());
return functions;
}
}
public class I18nCustomFunction implements com.mitchellbosecke.pebble.extension.Function {
private final List<String> argumentNames = new ArrayList<>();
public I18nCustomFunction() {
this.argumentNames.addAll(Arrays.asList("bundle", "key", "locale", "params"));
}
@Override
public List<String> getArgumentNames() {
return this.argumentNames;
}
@Override
public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
String basename = (String) args.get("bundle");
String key = (String) args.get("key");
String locale = (String) args.get("locale");
Object params = args.get("params");
ResourceBundle bundle = ResourceBundle.getBundle(basename, forLanguageTag(locale), new UTF8Control());
Object phraseObject = bundle.getObject(key);
if (params == null) {
return phraseObject;
}
if (params instanceof List) {
List<?> list = (List<?>) params;
return MessageFormat.format(phraseObject.toString(), list.toArray());
}
return MessageFormat.format(phraseObject.toString(), params);
}
public static Locale forLanguageTag(String languageTag) {
String[] splits = languageTag.split("\\-");
return splits.length > 1 ? new Locale(splits[0], splits[1]) : new Locale(splits[0], "");
}
}
Upvotes: 1
Reputation: 116
Currently, it is not supported. It always use the locale from the spring context. I suggest that you provide a custom function and use it for your need.
Upvotes: 1