dust-intl
dust-intl copied to clipboard
formatMessage and html-formatting
I often find myself wanting to include a string with some formatting into a translated sentence. E.G "The user Sigmund performed this commit"
Looking at the source code it seems formatMessage allways performs html-escape (unless you hit the precompiled format optimization which doesn't and is probably a security issue...)
Recent versions of dustjs-linkedin allows you to return data from a helper and utilize the dustjs filters to do escaping. With this approach the following diff:
diff --git a/src/helpers.js b/src/helpers.js
index 2037abd..cc69305 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -240,14 +240,12 @@ function registerWith (dust) {
// optimization for messages that have already been compiled
if ('object' === typeof msg && 'function' === typeof msg.format) {
- chunk.write(msg.format(params));
- return chunk;
+ return msg.format(params);
}
formatOptions = contextGet(context, ['intl', 'formats']);
locales = getLocales(chunk, params, context);
formatter = getMessageFormat(msg, locales, formatOptions);
- chunk.write(dust.escapeHtml(formatter.format(params)));
- return chunk;
+ return formatter.format(params);
}
}
will allow formatMessage to be used like this:
{@formatMessage _key="mystring" user="<strong>Sigmund</strong>" filters="|u"/>
If filters are not set the default is still to html-escape, so it should be backwards compatible with existing templates.
I'm facing the same issue. Our intl team is now loving working with react-intl and how we can easily let them tweak the messages, but we still need to split strings if they contain markup when using dust-intl.
Any chance that something like this suggestion could be accepted? Thanks!
For the record I ended up writing my own dust-helper like this:
dust.helpers.blockTrans = function(chunk, context, bodies, params) {
var template = context.get('_')[params.key];
var subContext = {};
for (var key in bodies) {
subContext[key] = "";
}
var tap = function(data) {
subContext[key] += data;
return "";
};
for (key in bodies) {
chunk.tap(tap).render(bodies[key], context).untap();
}
for (key in bodies) {
template = template.replace('{' + key + '}', subContext[key]);
}
chunk.write(template);
return chunk;
};
Which could be used from a template like this:
{@blockTrans key="mandatory_clients_overview_more"}
{:clients}
{#clients}
<strong>{name}</strong>{@sep}, {/sep}
{/clients}
{:rest}
{rest}
{/blockTrans}
With a translation string like this: "This organization has listed some mandatory clients, such as {clients}, and {rest} more"