ember-intl
ember-intl copied to clipboard
Allow array of strings
What would you guys think about allowing arrays of strings for translations? It seems right now if the value under the key is an array, it assumes the translation is missing, but I would like it to return the array instead.
In that scenario, what about interpolation of variables?
@buschtoens these particular strings do not have any variables, just plain strings we want to change per locale. It's basically a bulleted list that we will change per language.
What would the output look like? The result of the translation look ups concatted together with/without a separator? Translations that take arguments would be difficult to express then.
@jasonmit it should just return the array as is, no concat, and no arguments.
I would imagine an external API like this:
welcome-steps:
- Hello, {name}!
- First you'll need to blah blah.
- And then you'll need to foo bar.
- Thanks for joining, {name}!
<ul>
{{#each (t "welcome-steps" name=this.user.name) as |step|}}
<li>{{step}}</li>
{{/each}}
</ul>
<ul>
<li>Hello, Jan!</li>
<li>First you'll need to blah blah.</li>
<li>And then you'll need to foo bar.</li>
<li>Thanks for joining, Jan!</li>
</ul>
I'm still not 100 % convinced that returning arrays from locales is a good pattern, but I found myself in need of this a few times as well.
Adding this feature would also raise the following questions:
- What about nested arrays?
- What about non-string elements in an array?
- What about objects?
@buschtoens I'm just looking for raw array support. I think arrays are a special case, and I am okay with them not supporting passing variables, and just returning a raw array of strings.
Sure, I understood that! But we also need to think about how this might be used not only in your specific case. 😊
I definitely see why it may be appealing to support returning lists from {{t}}, as I have code like this myself in a few places:
terms-and-conditions:
p1: I am the Lord thy God, thou shalt not have any strange gods before Me.
p2: Thou shalt not take the name of the Lord thy God in vain.
p3: Remember to keep holy the Sabbath day.
...
<h1>Terms and Conditions</h1>
{{#each (range 0 10) as |i|}}
<p>
{{t (concat "terms-and-conditions.p" i)}}
</p>
{{/each}}
I think we can answer the three questions in https://github.com/ember-intl/ember-intl/issues/982#issuecomment-534003624 with "We throw an assertion error". We can potentially in the future remove the assertion when we find that we want to support any of these cases.
I feel a bit uneasy with this proposal for two reasons (not saying I don't want it though!):
- Warning for missing / inconsistent translations across locales becomes more complicated. Could there reasonably be locales which have a different list length?
- Locales should not encode data. This is a somewhat mini-step into that direction.
I'm keen to hear more opinions regarding this proposal. IMO though, if we implement this, we should support variable interpolation as described in https://github.com/ember-intl/ember-intl/issues/982#issuecomment-534002849.
So without adding this, how would you support arbitrary lengths of content per locale? My current workaround is to make it one big multiline string, but I would prefer to be able to treat each line as a separate entity.
So you basically answered my question 😄
Could there reasonably be locales which have a different list length?
Can you describe your use-case with an example maybe, where the list length differs between locales?
I do not know of a specific example where the lengths could differ. In our case, we use this for guiding questions, to help users decide how to score a category. I could feasibly see different locales having different numbers of guiding questions.
Alright, thanks! From my POV this is a reasonable feature to ask for and I am in favor of implementing it, but would like to hear some more opinions first (cc @jasonmit @Turbo87).
We can make the missing key check for list length configurable and enable it for all keys by default.
While the files that we use are not really standardized there are still quite a few tools that support them in the current way. as in: ICU messages in YAML/JSON files. I fear that if we changed our format to support arrays in some form we would lose that advantage.
If we don't care about supporting tools then we could also encode raw JSON in the translation strings instead.
@Turbo87 Could you elaborate on the tools that use the format and what would be breaking?
I'm mostly talking about translation tools like Crowdin, etc.
@Turbo87 I see this as a feature that would be opted into. So if your project decided to adopt arrays as a translation value it would then possibly break tooling like Crowdin. Otherwise, I believe you wouldn't impacted.
We can even make it configurable to avoid and throw if an array is discovered as a value.
Opt in sounds fine to me. We do not use any other tools.
Another solution could be to use suffixes such as textBlockSection1, textBlockSection2 where …sectionX is the suffix.
You'd then iterate over them using JS + exists to see how many 'sections' you have in a particular locale. Could be coupled with the requireTranslation function where you'd check the key suffix to know if it's required or not (to avoid the warning in other locales).
@rwwagner90 Would that be a workable solution for your use-case?
If so, then this could mostly be solved using improved documentation around that scenario.
@sandstrom there are multiple ways to use the existing API, but I don't think exposing an array as is should be too difficult to support either.
Hi there. I think there can also be use-cases for objects. For instance I'm thinking of country lists and similar data.
I'm used to give a partial translation with i18n tools and get the underlying list of translations.
An alternative could be to expose a low primitive that would allow access to all the key/value pairs below a given key or something. That would allow for arrays as much as objects.
Closing this issue, as I won't be pursuing the feature at the moment and want to keep the maintenance cost low. If I understood the original proposal correctly, the current API (e.g. {{each}} and translation keys with suffixes) does allow an implementation.