News for hackers. Stuff that matters.
Re:Fluent 1.0: a localization system for natural-sounding tr... by stasm on Wednesday April 17, 2019 @05:57AM (#19681166)
This is a great point and something that we've seen come up very often in building UIs. The good practice which we recommend to developers at Mozilla is to avoid splitting or nesting messages, because it makes it harder for translators to see the entire translation at once.

We've taken a layered approach to designing Fluent: what we're announcing today is the 1.0 of the syntax and file format specification. The implementations are still maturing towards 1.0 quality, but let me quickly describe what our current thinking is.

For JavaScript, we're working on low-level library which implements a parser of Fluent files, and offers an agnostic API for formatting translations. On top of it we hope to see an ecosystem of glue-code libraries, or bindings, each satisfying the needs of a different use-case or framework.

I've been working on one such binding library called fluent-react. It's still in its 0.x days, but it's already used in a number of Mozilla projects (e.g. in Firefox DevTools). In fluent-react translations can contain limited markup. During rendering, the markup is sanitized and then matched against props defined by the developer in the source code, in a way that overlays the translation onto the source's structure. Hence, this feature is called Overlays. See https://github.com/projectfluent/fluent.js/wiki/React-Overla....

Here's how you could re-implement your example using fluent-react. Note that the <a>'s href is only defined in the prop to the Localized component.

    <Localized
        id="confirm"
        $clickCount={7}
        a={<a href="..."></a>}
    >
        {"Please <a>click here {$clickCount ->
            [one] 1 time
           *[other] {$clickCount} times
        }</a> to confirm."}
    </Localized>
I'd love to get more feedback on ideas in fluent-react. Please feel free to reach out if you have more questions!
Re:Fluent 1.0: a localization system for natural-sounding tr... by lewisl9029 on Wednesday April 17, 2019 @06:13AM (#19681233)
I've seen a few libraries that use a similar approach of parsing strings for pseudo-elements and then matching them with React elements to avoid splitting up messages, but I've always felt a lot of resistance towards adopting something like that because it means incurring the runtime cost of parsing a string for elements when you can easily have hundreds or thousands of messages being rendered at once. (Call it a premature optimization if you must, but I've been bitten enough times in the past for adopting libraries/approaches that scaled poorly performance wise and had to pay the cost in untimely, painful refactors.)

I feel there's a fundamental impedance mismatch here because we're defining messages as strings but the rest of our UI as React components. I described here a potentially different component-oriented approach as an attempt to get rid of this impedance mismatch: https://news.ycombinator.com/item?id=19681129

I'd love to hear some thoughts on that approach from folks with more real-world experience working with i18n than I do (which is not a whole lot sadly, given the nature of the kinds of projects I've worked on in the past).

Re:Fluent 1.0: a localization system for natural-sounding tr... by ivan_gammel on Wednesday April 17, 2019 @07:10PM (#19687227)
I’ve been trying to solve this problem in the resource4j library for Java, which can cache rendered strings, but in the end it’s always a memory vs performance problem. I didn’t publish any artificial benchmarks, but in couple real projects (resource4j+thymeleaf) performance impact was usually negligible.
Re:Fluent 1.0: a localization system for natural-sounding tr... by drdaeman on Wednesday April 17, 2019 @01:49PM (#19684788)
> `[one] 1 time *[other] {$clickCount} times`

How does this work for languages that have more complex pluralization rules?

E.g. in Russian it's "1 раз", "2 раза", "11 раз", "12 раз", "22 раза" and "55 раз" - the case depends on the number ending, with exceptions for 11, 12, 13 and 14.

Re:Fluent 1.0: a localization system for natural-sounding tr... by zbraniecki on Wednesday April 17, 2019 @03:38PM (#19685756)
That's a great question!

Fluent relies on Unicode Plural Rules [0] which allow us to handle all (as far as Unicode knows) pluralization rules for cardinal and ordinal (and range) categories :)

[0] http://cldr.unicode.org/index/cldr-spec/plural-rules

Re:Fluent 1.0: a localization system for natural-sounding tr... by stasm on Thursday April 18, 2019 @04:12AM (#19689533)
It's up to the localizer to define variants corresponding to the language's plural categories. For Russian, that's (one, few, many). Interestingly, this particular example could simplified to (few, *), because "раз" is good for both 1, 5, 11, 55, etc. See https://projectfluent.org/play/?id=7d22f87c04b23b86d9f9149d5... for an example of this in action.

Authoring tools can help here, too. Pontoon, Mozilla's translation management system, pre-populates plural variants based on the number of plural categories defined in Unicode's CLDR.

Re:Fluent 1.0: a localization system for natural-sounding tr... by schoen on Wednesday April 17, 2019 @03:13PM (#19685522)
Re:Fluent 1.0: a localization system for natural-sounding tr... by Vinnl on Wednesday April 17, 2019 @06:00AM (#19681180)
Would this also allow for translating e.g. the <a>'s `title` attribute, or e.g. an `aria-label`?
Re:Fluent 1.0: a localization system for natural-sounding tr... by stasm on Wednesday April 17, 2019 @06:09AM (#19681217)
It's something that I definitely plan to add. There's even an open issue about it! https://github.com/projectfluent/fluent.js/issues/185
Re:Fluent 1.0: a localization system for natural-sounding tr... by Vinnl on Wednesday April 17, 2019 @06:19AM (#19681257)
Great! It sounds like a very cool project to work on :)
Re:Fluent 1.0: a localization system for natural-sounding tr... by Zenbit_UX on Wednesday April 17, 2019 @09:47AM (#19682492)
What's stopping you from doing that now? Just add a new translation for those labels in the source document and bind it to the attribute tag.
Re:Fluent 1.0: a localization system for natural-sounding tr... by chrischen on Wednesday April 17, 2019 @03:41PM (#19685782)
You should take a look at js-lingui. Child components are automatically converted to symbols by way of a babel-macro (no run time parsing of complex translations).
Re:Fluent 1.0: a localization system for natural-sounding tr... by Andrex on Wednesday April 17, 2019 @09:37AM (#19682400)
Why fluent-react and not (in addition to) fluent-web-components? :(
Re:Fluent 1.0: a localization system for natural-sounding tr... by Vinnl on Wednesday April 17, 2019 @09:48AM (#19682494)
One advantage I can imagine is that you can prerender the React components, outputting e.g. plain HTML. With tools like e.g. React Static, that means you can somewhat ergonomically generate different static websites for different languages, avoiding the runtime costs of looking up the correct strings.
Re:Fluent 1.0: a localization system for natural-sounding tr... by cbenz on Friday April 19, 2019 @05:37AM (#19698158)
Using the Svelte JS library (https://svelte.technology) you can have both: server-side rendered components [1] and compile to web components (custom elements) [2]

Another advantage is that the components compile to vanilla JavaScript, so we don't rely on a runtime library to run the application.

[1] https://svelte.technology/guide#server-side-rendering

[2] https://svelte.technology/guide#custom-elements