django-ftl / fluent-compiler

High performance Python implementation of Fluent, Mozilla's l10n language
Other
21 stars 4 forks source link

Ability to handle fallback properly #1

Open spookylukey opened 4 years ago

spookylukey commented 4 years ago

There are a number of ways that we may want to "fall back" from the desired locale to another locale when formatting messages.

  1. When the requested message is entirely absent from the requested locale, but is present in the default.
  2. When the requested message is present, but contains a reference to a message or term that is not present.

Using fluent_compiler, we can currently handle situation 1 easily 'externally' by the fact that missing messages can be detected (e.g. FluentBundle.format will raise KeyError etc.) and we can do fall back.

We cannot do 2 in this way however, we just get a partial message with a returned error.

In addition, there are 2 ways that both of these can occur:

A. Accidentally, where we have an incomplete translation B. Deliberately, where we have a translation that is just a variant of another.

(See https://discourse.mozilla.org/t/on-message-and-termreferences/53217/4)

For 2 we need a fallback mechanism built into fluent_compiler, and also to do 1.B. nicely (so that it is distinguished from an error condition and won't be logged as a missing message).

In terms of implementation, the process would be something like:

  1. Compile the default or base FTL files using compile_messages
  2. Compile the others, passing the appropriate CompiledFtl objects as some kind of Fallback strategy object that gets passed to compile_messages which can do something clever with them to find the things to fall back to.

Another fruitful implementation strategy might be to replace the {id: message_or_term} dict that gets passed around with a more complex object that implements the fallback strategy, and can report whether fallback happened or not, and so cooperate in the compilation process somehow.

We might not have the entire process baked into fluent_compiler itself, but would make the bits available for django-ftl etc. to be able to do this.