On 27.07.2008, at 11:07, iain wrote:
> The locales.yml has been added for multiple locales for one language.
> Locales like en-GB and en-US are all english and although there is
> difference between them, you mostly wouldn't implement that.
Ah! Ok, so that touches the topics of
a) hierarchically organized locale data (en-US and en-GB can both
share most of en and only add a couple of differences) and
b) locale fallback (if the client requests en-GB, but there's only en
defined, en will be used)
These are both topics which we've discussed a lot initially but
finally abstained from doing anything about it. They are very
controversial topics to say the least ... and it's part of what I
meant in my blog post with "we initially tried to accomplish way too
much in Rails core" ;)
>> In your code comments you're using 'nl-NL' as an example for a locale
>> while onhttp://github.com/iain/i18n_yaml/wikis/getting-startedthere's
>>
>> I18n.default_locale = 'english'
>>
>> I think we all should standarize on using RFC4646 [1] compliant
>> locales both for providing locales data and documentation to make
>> sure
>> our data is more exchangeable.
>
> I tried to group en-US and en-GB and stuff. I'm struggling a bit to
> know how to properly interpret HTTP_ACCEPT_LANGUAGE and locales.
> Should I just split('-') so I only look at the first part, or group it
> with locales.yml? What's your advise on this?
As for parsing locales I think you should stick to what RFC4646
defines. E.g.:
http://trac.globalize-rails.org/trac/globalize/browser/branches/saimon/trunk_with_rfc4646_support/lib/globalize/localization/rfc_4646.rb
http://svn.artweb-design.de/stuff/globalize/cldr/lib/cldr/rfc4646.rb
The most important parts are the language and region tags. The 2-3-
letter lowercase, first part denotes the language tag. The 2-letter
uppercase second part (or third, if there's also a script tag given,
which would go to the second position then) denotes the region tag.
Thus en just means "English", while en-US means "English as spoken in
the *region* USA" (regions not necessarily are countries).
As far as I know HTTP_ACCEPT_LANGUAGE is a huge issue because
virtually nobody actually configures that header for their browser -
and browsers used to stick whatever crap into there. Maybe that
situation has improved, though.
I think we could all benefit from someone researching this matter and
then implementing a small plugin that does exactly that: do a
reasonable pick from HTTP_ACCEPT_LANGUAGE based on the available
RFC4646 locales in an app.
So ... if you'd want to jump at that, that would be awesome :)
> Damn those pesky non-latin languages ;) Anyway, my plugin is still
> Simple. I'm not trying to make a one-size-fits-all solution. When you
> want to do japanese, arabic or stuff, it might be better to use
> Globalize?
I've got some responses from the Japanese people that I've contacted
recently. (Really, really, really exciting! *jumps* :D I totally hope
to be allowed to forward some of the news.)
Basically the answer is:
There's no problem with reading Japanese translations from YAML (as
long as utf-8, of course) - so everybody can do that. There's still a
huge problem with writing Japanese to YAML, though, because YAML
serializes this sort of data to a binary format - which completely
defeats the purpose of YAML as a format that makes manual editing easy
of course.
So, the advice is: If you want to write translations (and want your
solution working for a larger audience), don't use YAML. If you only
want to read from YAML, everything's cool with that :)
> PS. Do you have a list of things that are translatable in the Rails
> core? I've been looking for it, but somehow I think I'm missing a lot.
Actually, no. Although that would be a good idea.
The only lists available are the en_US.rb files in the various Rails
libraries. But of course that does not include translateable dynamic
things that are also already there (like model attributes).
thanks for registering :)
On 30.07.2008, at 14:26, habermann24 wrote:
> I can't get this plugin to work with form error messages. It says
> "can't convert array into string" (error_messages_for) ...
>
> I'm trying to fix this but i have no idea why this is happening...
I'd have to try that myself to answer the question. If you can't fix
it maybe it's easiest if you'd provide a failing test case?
> Other than that...my question would be, if it would be possible to
> translate the default rails error messages aswell!?
The Simple Backend which Iain uses overwrites existing keys and
translations iirc. Thus, if you make sure to load your custom
translations after the Rails frameworks have been loaded that should
work fine.
Sounds like a plan.
Although, maybe the nested directory structure makes it hard to see
what's there in one glance? Also, in an editor like Textmate where you
only see the filename on the tab, maybe it's more convenient to have
the full locale on the filename? Just mulling ...
-- en
`-- en.yml
`-- en-US_rails.yml
`-- en-US_colors.yml
Not sure ...
Btw ... I guess right now this certainly will be overkill, but at some
point in the future we might want to try to wrap our head around
private-use subtags. These can be used to define such variants like
"formal english" vs. "informal english" etc. E.g. in German you'd
address the user with "Sie" in a formal way, but with "Du" in an
informal way, in English this is both just "You". Of course one can
often work around these things but in the end it might make sense to
provide different translation files for variants like these and let
the user choose either de-x-formal or de-x-informal (in this example).
>> As far as I know HTTP_ACCEPT_LANGUAGE is a huge issue because
>> virtually nobody actually configures that header for their browser -
>> and browsers used to stick whatever crap into there. Maybe that
>> situation has improved, though.
>
> In the case of firefox: if you install the dutch version, dutch (nl-
> NL) is automatically added to your header. My guess is IE does this as
> well. So if you don't adjust it manually you get the default language
> of the browser.
Yeah, maybe it's more usable today than it used to be.
>> I think we could all benefit from someone researching this matter and
>> then implementing a small plugin that does exactly that: do a
>> reasonable pick from HTTP_ACCEPT_LANGUAGE based on the available
>> RFC4646 locales in an app.
>>
>> So ... if you'd want to jump at that, that would be awesome :)
>
> I can extract the HTTP_ACCEPT_LANGUAGE identification from my plugin
> ofcourse. Make something nice and i18n independent.
Cool!
>> So, the advice is: If you want to write translations (and want your
>> solution working for a larger audience), don't use YAML. If you only
>> want to read from YAML, everything's cool with that :)
>
> You mean, as in automatic writing? I mean, I'm guessing that people
> who understand japanese can edit a .yml file themselves. If the
> YAML.load_file() method works fine with utf8, than I see no problem.
I meant like in Globalize where you can have an UI to store
translations to the backend and such.
So for a solution like your's that's all fine.
>> Actually, no. Although that would be a good idea.
>
> Working on it...
Great :)
Thanks so much for taking the time for this. There's so much going on
right now that I barley find the time to answer the most important
mails :)
On 30.07.2008, at 23:06, iain wrote:
> in the file: vendor/rails/activerecord/lib/active_record/
> validations.rb on line 171, it reads a variable called "message" which
> turns out to be an array.In my testcase it was this:
> [:"custom.product.name.blank", :blank] for a Product model and a name-
> field that couldn't be blank.
I'd still have to look into that more closely, but it seems really odd
to me that this would be an array at this point.
> * Cool that you can define custom error messages per model in you
> lang-
> files instead of in the controller \o/
> * What is that "custom" scope doing there? Seems like an odd name.
We just wanted to pick a name for a namespace that definitely would
not conflict with any other namespaces. What would be a better name?
The purpose is, like you said, to be able to define custom error
message translations per model.
> * There's no "try-these-keys" function in i18n functionality. You
> can't supply I18n.translate an array of keys, to try out and use the
> first translation it finds. It just translates them both and
> concatenates them. Maybe there should be? I'm not sure. Can you
> guarantee this is the only case which produces an array?
I think there is this functionality, although it's not an explicit
method:
I18n.t :not_here, :default => [:also_not_here, :default]
This would try to lookup :not_here, and :also_not_here and (when they
don't yield a result) finally fall back to the translation of :default.
Is that what you mean?
You can also supply #translate an array of keys. This has a different
meaning, though, it's defined as "bulk-lookup" and returns an array of
translations:
I18n.t [:foo, :bar]
# => ['Foo translation', 'Bar translation']
> * On lines 171 and 167 both reference the message. But at that time,
> shouldn't the messages be already translated into the errors-object?
> Shouldn't it be translated at the moment the error is raised, as
> apposed to when it's displayed? That would solve this problem anyway,
> because the display moment is not controlled by the user.
IIRC it should be translated in #generate_message (line 68). This
method is used in #add_on_empty, #add_on_blank and all the
#validates_* methods, e.g. on line 401 in #validates_confirmation_of
Thus, I really wonder why in error_messages_for message would be that
array like you said. What did we miss here?
> * i18n really _really_ needs a complete manual. I'm having a day off
> tomorrow. I'll see what I can write in between chores. ;)
YAY :)
On a slightly related note:
We want to start something useful on rails-i18n.org soon so that it
would be available by Rails Conf Europe. Most likely a blog + wiki for
starters.
If anyone wants to help building it, maybe even contribute to the
design, step up :D
On 02.08.2008, at 10:17, ry wrote:
> this brings up an important point: by moving away from a gettext style
> API it's not clear how one might extract the translatable strings in a
> source tree. certainly this can be done at run time, by making the
> application execute every possible behavior and adding the encountered
> translatable strings to a file. but what about for applications that
> are broken or not yet up and running. what about strings that only
> appear under very rare circumstances - no one wants to fill their "po
> file" (or yaml file or whatever) by clicking around on a website.
>
> Gettext explicitly requires you to your strings inside _( ) so that
> the parser could extract them from the source code. It seems I18N
> intends its users to maintain source code but also an external
> translations database.
We did not move away from a gettext style api :) What we did was
choosing an api for a different layer where no api existed at all. The
api in no way works against gettext, nor against any other
implementation. It's just a barebone api and still leaves the actual
implementation to plugins.
So you can both:
- implement a backend which uses gettext for storing and looking up
translations (and we hope there will be one for gettext really soon)
- define Object#_ for the frontend (Rails, Merb, ... whatever
framework), so you can use _() in your applications and grep for that
(with whatever tool)
Also, I agree with Iain that grep'ing the source code is not really a
safe solution either. (Which does not mean you should not use it of
course, mileages vary - especially when it comes to I18n.) The only
way to really be safe about missing translations is to have a complete
test suite . The api also supports this kind of approach by defining
different exception handlers.
I've done a basic design and set up a blog and wiki: http://rails-i18n.org/
The site is using adva_cms which is a project I'm currently working on
(http://github.com/svenfuchs/adva_cms). It's still pre-alpha, so it's
a bit wobbly but should already work for most basic things (including
the wiki).
Why would you want to extract strings from rails-core? Translations
used in rails-core need to be available in the shipped en-US
translation files, so they're already known.
> Not that I am against having a test suite that has full coverage, but
> why should one tie the functionality of i18n to a test suite when
> there is no need.
Please, nobody ties anything. It's just a practice which is considered
preferrable by some.
> If rails simply adopted the gettext _() API the
> could still be independent back-ends and people would still have the
> possibility of extracting translatable strings with reliability.
I'm not sure what exactly you mean by "adopt the gettext _() API".
We have a t() API so instead of
_("Hi %s.")
it's
t(:"Hi {{name}}")
... if you want to use a default string as a key which you can do in
your plugin if you want.
Am I missing something?
Maybe this is, again, the misunderstanding that the I18n API shipped
was also a fullfledged L10n solution. *It's not.* It really is not. We
still have to build on this. We're still supposed to implement our own
needs as plugins (or whatever libraries).
Yes, I was aware of these implications.
You can do exactly that. The I18n API does not hold you back from
implementing and using this. It's outside of the scope of the API.
Maybe what you really mean though is that you would have liked to see
a common agreement across all I18n plugin devs in the Rails world to
support this style.
This certainly would not have been achievable for the simple reason
that not everybody wants to use it. I can tell you from the
discussions we had since September last year that this style
definitely would not have been something that the developers of all
today's major plugin's developers would have wanted to adopt. So it
would not have been an option.
Let alone the restriction not to wrap method calls (which would be a
significant limitation alone for the Rails core patch implementation)
many people do not agree with the "default translations as keys"
approach any more. Sure, it was the dominant approach for a long time
and Gettext, Gibberish *and* Globalize supported them in one way or
another but it also has caused quite some problems.
That said, the I18n API still does in no way limit you from doing
exactly that. You just can't expect everybody else to do it. But
that's been true as long as there was Rails I18n.
BTW, I thought I18n didn't care about how locales are formatted. But it
isn't case-insensitive.
So I updated the plugin :)
The "default translations as keys" doesn't matter to me and I am happy
with your approach in this matter. What is important is the
possibility to extract keys outside of runtime. I don't agree that
this is a triviality.
What happens when some Rails plug-in developer adds some call to
I18n.t()? How are application developers notified of this so they can
make the appropriate translation?
I've heard three unsatisfactory solutions:
1. have all developers manually maintain both the source code and an
external database
2. grep -R "I18N.t"
3. Have tests with 100% coverage, write a collection back-end, and
collect all keys while running the tests.
ry
On 06.08.2008, at 12:11, ry dahl wrote:
> The "default translations as keys" doesn't matter to me and I am happy
> with your approach in this matter. What is important is the
> possibility to extract keys outside of runtime. I don't agree that
> this is a triviality.
Agree with whom? Nobody said it's a triviality, or did I? C'mon.
From my point of view "possibility to extract keys outside of
runtime" is just something that a) can not be part of the scope of the
API (obvioulsy) and b) won't be easily solved for *all* of the Rails
I18n landscape because it relies on conventions that neither can be
enforced programmatically nor will be acceptable (or implementable)
for many developers (at least that's just what I'd expect based on
previous discussions, i well might be wrong).
That said, again, you can do that. If it's important to you, why don't
you get started with it?
> What happens when some Rails plug-in developer adds some call to
> I18n.t()?
With the current implementation and the Simple backend in Rails?
Nothing.
> How are application developers notified of this so they can
> make the appropriate translation?
The plugin dev will have a translations file included with the plugin.
The application dev can look at it.
> I've heard three unsatisfactory solutions:
> 1. have all developers manually maintain both the source code and an
> external database
> 2. grep -R "I18N.t"
> 3. Have tests with 100% coverage, write a collection back-end, and
> collect all keys while running the tests.
Make 2. your favorite gettext scrape tool (which I meant by "grep for
it") and implement your own helpers to be able to use _(). That won't
work for Rails and plugins, but it's a step forward. It relies on the
app dev to comply with your conventions, but that's been true since
the invention of Gettext, so it will work for *some* people and that
would be already great.
If you'd like to see Rails patched to better work with this sort of
approach or convention, we're certainly open to discussion. But please
provide reviewable code first that would leverage this sort of
functionality. Again, this scraping toolkit in my opinion could
neither go into the I18n gem nor Rails itself directly.
Please implement your ideas as a plugin or gem or whatever library. It
would be definitely a very useful addition. We'll certainly be happy
to help if we can.
sorry - I don't mean to come across as mean - just being direct :)
i do greatly appreciate all the work this group has been doing
So the main problem is allowing calls to I18N.t to be wrapped in other
functions. Unless there is a good and strong objection to it, I would
suggest making this a convention. Then someone can write a parser to
extract keys automatically and it will solve the issue for everyone.
Your right, it cannot be enforced programatically but nevertheless key
extraction is useful.
I don't see why I18N.t calls should be wrapped, anyway.
ry
no problem :)
> i do greatly appreciate all the work this group has been doing
>
> So the main problem is allowing calls to I18N.t to be wrapped in other
> functions. Unless there is a good and strong objection to it, I would
> suggest making this a convention.
So what would be the scope of the convention? Rails core? All plugins?
Or just: everything that wants to be compatible with the scraper tool?
I see no problem with the latter at all, except of course, there's no
scraper, yet :D
There might be problems with plugins (depending on what they're trying
to solve). And with regards to Rails core I'm pretty sure there are a
couple of places where you could not implement this convention. Maybe
that's wrong though and just results from my limited experience with
the convention.
So, I guess, before we could agree on the convention somebody would
need to look at Rails core, check if it's a possible thing to do and
propose changes if applicable.
?
> Then someone can write a parser to
> extract keys automatically and it will solve the issue for everyone.
>
> Your right, it cannot be enforced programatically but nevertheless key
> extraction is useful.
>
> I don't see why I18N.t calls should be wrapped, anyway.
You gave the following example and said this should not be used:
def my_translation_function(str)
t(str)
end
my_translation_function("hello world")
You also said that:
> Gettext explicitly requires you to your strings inside _( ) so that
> the parser could extract them from the source code
and
> I18N.t cannot be wrapped in functions it must be used
> directly on strings.
So we also can't do:
scope = 'ActiveRecord.error_messages'
msg = 'too_long'
I18n.t :"{scope}.#{msg}"
Right?
I guess this limitation could pose quite some problems on the Rails
libraries and maybe plugins.
E.g. ActiveRecord validations look up dynamically defined keys of
course. Another example are translations for column names.
How would these things be looked up then in order to work with the
scraper?