Does Pebble templating engine provide any methods to manually designate i18n locale

317 Views Asked by At

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>
2

There are 2 best solutions below

0
On BEST ANSWER

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.

0
On

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], "");
    }
}