What we've come up with is a simple variant on JText::sprintf which
covers most cases easily and gives Russian or similar languages a
workaround. The new function is:
JText::__('KEY', $count [, $arg2])
That's a double underscore there (easy to remember, want plural
support, use a plural underscore).
The first argument is the key, the second is the count. The method
looks for a key like:
KEY_$count which could be something like:
KEY_0
KEY_1
KEY_2
KEY_42
If the key is found, that key will be used. If not, the original KEY
is used. A real example could be:
COM_WEBLINKS_N_ITEMS_DELETED="%d weblinks successfully deleted"
COM_WEBLINKS_N_ITEMS_DELETED_1="%d weblink successfully deleted"
where usage is:
$this->setMessage(JText::__('COM_WEBLINKS_N_ITEMS_DELETED', count($ids)));
As you can see, a zero case can easily be supported, as can any other
number variants. The rule of thumb is to make the main key suit the
broad plural case (usually >1 but sometime >=5 in some languages) and
use the KEY_1, KEY_? for the exceptions.
Seems to be working satisfactorily at the moment.
Regards,
Andrew Eddie
http://www.theartofjoomla.com - the art of becoming a Joomla developer
--
You received this message because you are subscribed to the Google Groups "Joomla! CMS Development" group.
To post to this group, send an email to joomla-...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-cm...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/joomla-dev-cms?hl=en-GB.
> Soooo... JM and Dennis Hermatski and I have been throwing around some
> ideas about how to handle pluralisation correctly.
> [...]
> If the key is found, that key will be used. If not, the original KEY
> is used. A real example could be:
>
> COM_WEBLINKS_N_ITEMS_DELETED="%d weblinks successfully deleted"
> COM_WEBLINKS_N_ITEMS_DELETED_1="%d weblink successfully deleted"
Great solution. Please ensure, that also definitions like
COM_WEBLINKS_N_ITEMS_DELETED="%d weblinks were successfully deleted"
COM_WEBLINKS_N_ITEMS_DELETED_0="No weblink was deleted"
COM_WEBLINKS_N_ITEMS_DELETED_1="The weblink was successfully deleted"
will work with the implementation (i.e., the %d placeholder may or may
not be present).
Niels
You are read my thoughts? I was thinking about this today.
But, IMHO, your solution is not ideal. As a russian and ukrainian speaker
I found that it is not convenient to specify "count" literally, as a
number.
Instead of "count" we should specify a rule by which words are changing
depending on "count".
For example, I want to print a message which informs a user how much books
were found by its search query.
The word "book" in russian will be "kniga".
The word "found" in russian will be "naidena".
So:
0 knig naideno.
1 kniga naidena.
2-4 knigi naideny.
5-20 knig naideno.
21 kniga naidena.
22-24 knigi naideny.
25-30 knig naideno.
...
100 knig naideno.
101 kniga naidena.
112-114 knigi naideny.
115-120 knig naideno.
121 kniga naidena.
...and so on.
The rule here is that we should print:
- "$count kniga naidena" if `($count % 10 == 1 && $count != 11 && $count
% 100 != 11)`
- "$count knigi naideny" if `($count % 10 > 1 && $count % 10 <= 4 &&
!in_array($count, array(12, 13, 14) && !in_array($count % 100, array(12,
13, 14))`
- "$count knig naideno" in all other cases
How I can use this rule now?
Only from PHP-code. But localization should not touch it. Right?
So I propose to discuss this subject here more thoroughly.
PS:
See how the symfony guys made this:
http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19#chapter_19_sub_translations_with_arguments
--
Artyom
@Niels
COM_PLUGINS_N_ITEMS_UNPUBLISHED_1="A plugin was successfully disabled"
is working OK.
As well as
MOD_STATUS_MESSAGES="%d Messages"
MOD_STATUS_MESSAGES_0="No message"
MOD_STATUS_MESSAGES_1="A message for you"
with the code
$output[] = "<span class=\"$inboxClass\"><a href=\"$inboxLink\">".
JText::__('MOD_STATUS_MESSAGES', $unread) . "</a></span>";
On 15 avr, 17:26, "Artyom Bisyarin" <arts...@ukr.net> wrote:
> On Thu, 15 Apr 2010 16:16:28 +0300, Andrew Eddie <mambob...@gmail.com>
> See how the symfony guys made this:http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19#chapter_19_s...
>
> --
> Artyom
> @Niels
> COM_PLUGINS_N_ITEMS_UNPUBLISHED_1="A plugin was successfully disabled"
> is working OK.
Great.
Niels
--
| http://www.kolleg.de · Das Portal der Kollegs in Deutschland |
| http://www.bsds.de · BSDS Braczek Software- und DatenSysteme |
| Webdesign · Webhosting · e-Commerce · Joomla! Content Management |
------------------------------------------------------------------
> But, IMHO, your solution is not ideal. As a russian and ukrainian speaker
> I found that it is not convenient to specify "count" literally, as a
> number.
Maybe it is time to refactor the Russian language ;-)
> Instead of "count" we should specify a rule by which words are changing
> depending on "count".
>
> For example, I want to print a message which informs a user how much books
> were found by its search query.
> The word "book" in russian will be "kniga".
> The word "found" in russian will be "naidena".
> [...]
> The rule here is that we should print:
> - "$count kniga naidena" if `($count % 10 == 1 && $count != 11 && $count
> % 100 != 11)`
> - "$count knigi naideny" if `($count % 10 > 1 && $count % 10 <= 4 &&
> !in_array($count, array(12, 13, 14) && !in_array($count % 100, array(12,
> 13, 14))`
> - "$count knig naideno" in all other cases
> [...]
> See how the symfony guys made this:
> http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19#chapter_19_sub_translations_with_arguments
This would lead to definitions like this:
COM_EXAMPLE_N_BOOKS_FOUND="{n: n%10==1 && n%100!=11}%d kniga naidena|{n:
n%10>1 && n%10<5 && (n%100<12 || n%100>14)}%d knigi naideny|[0,+Inf]%d
knig naideno"
The last entry stands for "else", assuming that evaluation is stopped on
the first matching entry.
Parsing such constructs are very time consumpting, but I see the need
for a solution.
Just an idea:
How about defining suffices for the rules in the general xx_XX.ini file,
if needed, since the rules will be the same througout a given language?
COUNT_RULES="{n: n%10==1 && n%100!=11}_1|{n: n%10>1 && n%10<5 &&
(n%100<12 || n%100>14)}_234|[0,+Inf]"
defines suffix _1 for values matching {n: n%10==1 && n%100!=11},
suffix _234 for {n: n%10>1 && n%10<5 && (n%100<12 || n%100>14)} and no
suffix for [0,+Inf], i.e., everything else. In the language file we'd have
COM_EXAMPLE_N_BOOKS_FOUND="%d knig naideno"
COM_EXAMPLE_N_BOOKS_FOUND_1="%d kniga naidena"
COM_EXAMPLE_N_BOOKS_FOUND_234="%d knigi naideny"
If COUNT_RULES is empty or missing, the suffices are interpreted as
literals, as originally proposed.
With this, the rules would be parsed only once (into a string that will
be eval()uated or using lambda functions, with $count as argument. The
language file layout would not change from Andrew's proposal, and
Russian and Ukrainian language can be reflected.
Niels
KEY_0to4="Between 0 and 4"
KEY_5="Five"
KEY_6to10="Between 6 and 10"
KEY="None of the above"
Probably not much performance difference between parsing KEY_5 to be
"$x == 5" and parsing KEY_0to4 to be "$x >= 0 and $x <=4". Mark
On Apr 15, 1:11 pm, Niels Braczek <nbrac...@bsds.de> wrote:
> Artyom Bisyarin schrieb:
>
> > But, IMHO, your solution is not ideal. As a russian and ukrainian speaker
> > I found that it is not convenient to specify "count" literally, as a
> > number.
>
> Maybe it is time to refactor the Russian language ;-)
>
>
>
> > Instead of "count" we should specify a rule by which words are changing
> > depending on "count".
>
> > For example, I want to print a message which informs a user how much books
> > were found by its search query.
> > The word "book" in russian will be "kniga".
> > The word "found" in russian will be "naidena".
> > [...]
> > The rule here is that we should print:
> > - "$count kniga naidena" if `($count % 10 == 1 && $count != 11 && $count
> > % 100 != 11)`
> > - "$count knigi naideny" if `($count % 10 > 1 && $count % 10 <= 4 &&
> > !in_array($count, array(12, 13, 14) && !in_array($count % 100, array(12,
> > 13, 14))`
> > - "$count knig naideno" in all other cases
> > [...]
> > See how the symfony guys made this:
> >http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19#chapter_19_s...
That was helpful, though daunting to think about :)
Well, my only suggestion is that we keep the current solution for the
easier languages but we add in a rules parser as a special case. This
could be:
FOOBAR_N_ITEMS_DELETED="?{rule1}text1{rule2}text2{else}text3"
So what would happen is that we'd look at the first char of the string
and if we find an ? character (short for 'what the heck is going on
here'), we parse the string for rules. Each rule would just be a
valid PHP conditional test that we run through an eval() (though I
think I would try to disallow function calls, ie, in_array). How does
that sound to everyone?
Mark, that solution won't work because you don't know how many
combinations are in the language keys, and it's not always an easy
range calculation as we've found out.
Regards,
Andrew Eddie
http://www.theartofjoomla.com - the art of becoming a Joomla developer