Hello again!
(I believe we will meet each other on this forum every weekend from now on, itās the best I can do.)
This morning I did some research on various official formats used with gettext. Here there are some highlights:
Best/full implementation support both argument reordering and argument formatting. As a side note, most implements at least argument formatting and optional argument reordering
Your proposed formatting solve the problem of argument reordering very well, but for a full 100% implementation I suggest for us to find a standard for argument formatting options as well.
Some gettext formatting from other languages:
c-format:
āOnly %2$d bytes free on %1$s.ā
(index positional reordering and formatting)
python-format:
ā%(language)s has %(number)03d quote types.ā %
(named keys reordering and formatting)
ruby-format
ā%{name}s have %{count}d bookā
(named keys reordering and formatting)
%{key}[flags][width][.precision]type
php-format
āThe %2$s contains %1$d monkeys. That's a nice %2$s full of %1$d monkeys.ā
(index positional reordering and formatting - repeating same argument is allowed)
%[argnum$][flags][width][.precision]specifier
Letās come with a standard for erlang-format that have them all. In erlang we have ~ wich is the best candidate for a separator in between placeholder name and (optional) formatting metadata.
A Zotonic and Erlang io:format compatible solution could be:
{argname~F.P.PadModC}
Where:
- [argname] - is required
- [~F.P.PadModC] - is optional
- parameters could appear more that once in any order
- it has the advantage that can be easily parsed by existing implementation, we only need a split by ~ and a recursive io_lib:format each argument.
This will look like this:
{% trans "Hello {{foo}}, and this is {foo~16.16.0b} and this is the same {foo} and this is another {foo2}." foo=1234 foo2=5678 %}
What do you think about this proposed format?
If I get the green light from you I will start adding a format parser on both Zotonic and t__
As for the ets, in t__ I use almost the same approach, one table for all languages together per application repository - because with t__ one application can have more than one PO repo - thatās the only difference (plural and singular are kept toghether in the same ETS - a compound key makes the difference in between them when needed). Because both implementation and translator need to know if a plural is required (when generating POT files also this info is necessary) all implementation have some sort of a mark for plural forms. Most double the translation, giving 2 English forms - for one and for many). Rarely I saw usage a plural flag. In Zotonic this could look something like this I believe (notice the plural):
{% trans "There is {count} books" plural count=1 %}
or like this (it offers the default plural translation for missing plural translations) thatās why most provide this one/many - actually this looks like the preferred implementation in most advanced implementations:
{% trans "There is {count} book" "There are {count} books" count=56 %}
Another advantage of using both forms is you can easily create a compound key from the input that need to be translated - like this for example:
{language, āThere is a dogā} - ets key for a singular translation
{language, āThere is {count} bookā, āThere are {count} booksā} - ets key for plural
Full ets rows including the key:
{{es, āThere is one bookā}, [āsingular formā]}
{{ro, āThere is {count} bookā, āThere are {count} booksā}, [āplural form 1ā, āplural form 2ā⦠āplural form Nā]}
Then all you need left is a selector from the value list. Singular selector always returns the only available form, plural selector select the proper list element by formula and index N.
Please notice that gettext does not support mixing 2 variables or more EACH with plural forms together because the combinations that will result from, will make the translators job and implementations unpractical. Some languages having 6 plural forms⦠For this situation gettext simply recommend splitting the variables into different phrases/translations.
Like this:
{% trans "There is {count1} book." "There is {count1} books." count1=56 %}
{% trans "{count2} is reserved." "{count2} are reserved." count2=56 %}
NOT like this:
{% trans "There is {count1} book and {count2} are reserved" "There is {count1} books {count2} and are reserved" count1=56 count2=1 %}
ā you need more forms/combinations one/many, many/many, many/oneā¦