I've run into a rather interesting problem while working with ember-intl regarding usage of {{helpers}} (and some components) within the translation strings - particularly {{action}}, {{link-to}} and {{input}}. I'm working on a localization project for the first time so I'm not really well versed with conventions regarding internationalization, but I believe having inline actions and links would be a very common scenario. For example, consider the following string:
You can <a href="#" {{action 'allow'}}>allow</a> incoming message notifications
or <a href="#" {{action 'disable'}}>disable</a> them entirely. You can also {{#link-to
'settings.notifications' user}}manage notifications{{/link-to}} for your own profile.
Another variant of the above string used extensively within the app I'm working on uses inline {{input}} within the text for some controls, and sometimes even custom components.
Reading the discussions in #102 and #421 seem to suggest that there were discussions for a possible solution to this a couple of years ago but seems like nothing concrete really materialized from them. Are there any current guidelines or best practices for tackling these scenarios since I wasn't able to figure out the best approach from the documentation?
@UzEE not a solved problem. For link-to's I tend to use ember-href-to to solve that.
I'll keep this issue opened to start a dialog in discovering what it will take to support this.
@jasonmit Yes, link-to seems to be the easiest to work around with by using the ember-href-to addon. Unfortunately for my use case, the {{action}} helper usage far outweighs the {{link-to}} usage, so I'm still investigating possible solutions that work with that as well.
Hello! My team has been using a custom i18n solution, but we'd like to switch to using ember-intl. We have a solution for this called t-split. It can take a translation string like
Text before the link
{{#link}}
First text in the link
{{#strong}}text in the strong{{/strong}},
final text in the link
{{/link}}
text after the link
and be used in the template like this:
{{#t-split "translation.key" as |segment|~}}
{{~#if (eq segment.key "link")~}}
<a href="#" {{action "didClickLink"}}>
{{~#segment.content as |innerSegment|~}}
{{~#if (eq innerSegment.key "strong")~}}
<strong>
{{~innerSegment.content~}}
</strong>
{{~/if~}}
{{~/segment.content~}}
</a>
{{~/if~}}
{{~/t-split}}
It finds the special {{#separator}} and {{/separator}} tags in the translation string, converts into the appropriate nested structure, then yields them as nested contextual components. Any text not wrapped in special tags gets rendered automatically, so it only needs to handle the special text.
We could implement the same thing in ember-intl.
I really like your idea @mongoose700. I'm only wondering whether the syntax can be condensed somehow. 🤔
In cases where there's only one type of segment that appears in a particular string, you can leave out the ifs.
{{#t-split "translation.key" as |segment|~}}
<a href="#" {{action "didClickLink"}}>
{{~#segment.content as |innerSegment|~}}
<strong>{{innerSegment.content}}</strong>
{{~/segment.content~}}
</a>
{{~/t-split}}
This looks great, @mongoose700 — I want to try it.
Hmm, I was able to do this using a wrapper component and public methods from the service:
// t-plus.js
export default class TPlusComponent extends Component {
@service
intl;
get tokens() {
return this.intl.formatMessage(this.intl.lookup(this.args.path), this.args.options);
}
}
{{! t-plus.hbs }}
{{#each this.tokens as |token|~}}
{{~token~}}
{{/each}}
pas-form:
project-geography:
header: Project Geography
description: >
'<strong>' Is the proposed Project Area located in a current or former '<a href="https://www1.nyc.gov/site/hpd/services-and-information/urban-renewal.page" target="_blank" rel="noopener noreferrer">' Urban Renewal Area '<sup>'
{faIcon}
'</sup></a>'?'</strong>
<TPlus
@path='pas-form.project-geography.description'
@options={{hash faIcon=(component 'fa-icon' icon='external-link-alt' prefix='fas' fixedWidth=true)}}
/>
Is there something obviously wrong with this approach? Unsafe?
It looks like that could work, though that implementation doesn't have quite as much flexibility. You need anything you want to include in TPlus to be its own component, so it's harder to use for child components that themselves use contextual components that you want to customize, for example. I don't think it cleanly supports nesting.
Most helpful comment
In cases where there's only one type of segment that appears in a particular string, you can leave out the
ifs.