New file tree structure in latest Rails Edge I18n?

62 views
Skip to first unread message

glennpow

unread,
Sep 12, 2008, 8:20:45 AM9/12/08
to rails-i18n
I've been off the grid for a couple weeks and haven't been able to
keep up with developments.

Has the latest revision of I18n in Rails Edge adopted a new standard
file tree structure for the localization files?
I've seen quite a few tutorials using the "config/locales/en-US.yml"
scheme, rather than Iain's i18n_yaml plugin scheme (which I saw is
also deprecated).

I liked Iain's scheme because you could have multiple locales share
the same localization files (en-US and en-CA could share locales/en/
application.yml for example). Plus you could split the localizations
up into several files for easier navigability.

But if the decision was made against these concepts, please let me
know.

Sven Fuchs

unread,
Sep 12, 2008, 10:53:49 AM9/12/08
to rails...@googlegroups.com
Hey Glenn,

On 12.09.2008, at 14:20, glennpow wrote:
> I've been off the grid for a couple weeks and haven't been able to
> keep up with developments.
>
> Has the latest revision of I18n in Rails Edge adopted a new standard
> file tree structure for the localization files?

Nope, we left that out so far.

What we've changed in the I18n lib a couple of weeks ago is that it is
now possible to #load_translations from YAML or plain Ruby files
without the need of calling #store_translations manually any more.

> I've seen quite a few tutorials using the "config/locales/en-US.yml"
> scheme, rather than Iain's i18n_yaml plugin scheme (which I saw is
> also deprecated).

That's because Iain's original intend was to allow reading
translations from YAML. This is in the core gem lib now.

I honestly don't remember what the exact dir/file naming scheme was,
but we've added something like that to Globalize2 as well:

http://github.com/joshmh/globalize2/tree/master/lib/globalize/load_path.rb

You can use this separately from the rest of Globalize2 if you want.

This enforces a dir/file naming scheme like:
path/to/dir/all.yml
path/to/dir/en-US.yml
path/to/dir/en-US/*.yml

> I liked Iain's scheme because you could have multiple locales share
> the same localization files (en-US and en-CA could share locales/en/
> application.yml for example).

This is not solved in Globalize yet for static translations, but will
be added. It already works for model translations though.

iain hecker

unread,
Sep 12, 2008, 4:39:54 PM9/12/08
to rails-i18n
Hi Glenn,

Best practice is now to just load every file in your languages
directory, by putting this nice little one-liner in an initializer:

[:rb, :yml].each{|format|
I18n.load_translations(*Dir.glob("#{RAILS_ROOT}/app/locales/**/
*.#{format}")}

This is make sure that locales aren't read every time you view a page.

I'm working on a proper grouping function, to group locales with the
same language. Now that I'm more familiar with the I18n code I know
that my previous approach was not the way to go.

Other parts of i18n_yaml are being ported to new plugins too. Keep
watching my blog (iain.nl) for that.

Hope this helps

Iain

On Sep 12, 4:53 pm, Sven Fuchs <svenfu...@artweb-design.de> wrote:
> Hey Glenn,
>
> On 12.09.2008, at 14:20, glennpow wrote:
>
> > I've been off the grid for a couple weeks and haven't been able to
> > keep up with developments.
>
> > Has the latest revision of I18n in Rails Edge adopted a new standard
> > file tree structure for the localization files?
>
> Nope, we left that out so far.
>
> What we've changed in the I18n lib a couple of weeks ago is that it is  
> now possible to #load_translations from YAML or plain Ruby files  
> without the need of calling #store_translations manually any more.
>
> > I've seen quite a few tutorials using the "config/locales/en-US.yml"
> > scheme, rather than Iain's i18n_yaml plugin scheme (which I saw is
> > also deprecated).
>
> That's because Iain's original intend was to allow reading  
> translations from YAML. This is in the core gem lib now.
>
> I honestly don't remember what the exact dir/file naming scheme was,  
> but we've added something like that to Globalize2 as well:
>
> http://github.com/joshmh/globalize2/tree/master/lib/globalize/load_pa...

Clemens Kofler

unread,
Sep 12, 2008, 4:55:09 PM9/12/08
to rails-i18n
> [:rb, :yml].each{|format|
> I18n.load_translations(*Dir.glob("#{RAILS_ROOT}/app/locales/**/
> *.#{format}")}

Make that ['rb', 'yml'] and I'm with you on this one! ;-) No need to
have dozens of unnecessary to_s calls on start-up! ;-)

Iain Hecker

unread,
Sep 12, 2008, 5:14:29 PM9/12/08
to rails...@googlegroups.com
two actually, but it is rather silly...

glennpow

unread,
Sep 14, 2008, 11:44:25 AM9/14/08
to rails-i18n
So I'm running into a snag in the load order of the app.

I have a custom backend which I define in "lib/i18n_backend.rb". Now
my problem is that the load order is:
1. Rails core
2. plugins and initializers (I'm using the i18n plugin)
3. required libs (including i18n_backend)

But if I load my translations in an initializer as indicated in all
the newest demo apps, then my Custom backend will get set after these
loads, and thus wipe them out.
If I instead move the 'require "i18n_backend"' line of my
environment.rb file so that it's above the Rails::Initializer block,
then the I18n plugin will not be loaded at this time, and my Custom
backend (which extends Simple backend) will bomb with a unintialized
constant for I18n::Backend::Simple.
I could NOT extend Simple backend and write Custom completely, but
this just seems like a hack to get around an issue that has seemed to
plague the I18n module since it's birth. (The proper load order of
backends and translations)

What is the current thinking about this?

On Sep 12, 11:14 pm, "Iain Hecker" <i...@iain.nl> wrote:
> two actually, but it is rather silly...
>

Sven Fuchs

unread,
Sep 14, 2008, 3:32:10 PM9/14/08
to rails...@googlegroups.com
Hi Glenn,

well, we've been found the same problem while working on Globalize2,
too. Also Yaroslav pointed me to a related problem in his Russian
plugin.

There's no easy way to hook into the Rails initialization process
right before the Rails frameworks are initialized (which right now
load their translations to the Simple backend).

We've considered a lot of different approaches to this and in the end
our solution to this is to defer the actual translation loading to the
latest possible point. So clients (like Rails) would only register
translation sources to I18n and the backend would actually lazy-load
them when the first translation needs to be looked up.

See

http://github.com/svenfuchs/i18n/tree/master/lib/i18n.rb
http://github.com/svenfuchs/i18n/tree/master/lib/i18n/backend/simple.rb

glennpow

unread,
Sep 16, 2008, 3:56:49 AM9/16/08
to rails-i18n
Hi Sven,

Couldn't it also be just as easy not to have the new load_paths
method, but instead make the load_translations method perform with
this same behavior (only to store the paths given)? And then still
have the first translate call load these paths.
It seems like overkill to add a new method when the old one would
suffice. And it would cut down on confusion if this were to be merged
into the main source.


On Sep 14, 9:32 pm, Sven Fuchs <svenfu...@artweb-design.de> wrote:
> Hi Glenn,
>
> well, we've been found the same problem while working on Globalize2,  
> too. Also Yaroslav pointed me to a related problem in his Russian  
> plugin.
>
> There's no easy way to hook into the Rails initialization process  
> right before the Rails frameworks are initialized (which right now  
> load their translations to the Simple backend).
>
> We've considered a lot of different approaches to this and in the end  
> our solution to this is to defer the actual translation loading to the  
> latest possible point. So clients (like Rails) would only register  
> translation sources to I18n and the backend would actually lazy-load  
> them when the first translation needs to be looked up.
>
> See
>
> http://github.com/svenfuchs/i18n/tree/master/lib/i18n.rbhttp://github.com/svenfuchs/i18n/tree/master/lib/i18n/backend/simple.rb

glennpow

unread,
Sep 16, 2008, 4:41:23 AM9/16/08
to rails-i18n
On another note, I also found that if you simply have the 'require
"i18n_backend"' call at the beginning of your 'config/initializers/
locales.rb' file, and then set the I18n.backend and load your
translations later in that file, it all seems to work properly.
Not sure if this breaks Rails protocol (to have a require in an
initializer), but it works.

On Sep 16, 9:56 am, glennpow <glenn...@gmail.com> wrote:
> Hi Sven,
>
> Couldn't it also be just as easy not to have the new load_paths
> method, but instead make the load_translations method perform with
> this same behavior (only to store the paths given)?  And then still
> have the first translate call load these paths.
> It seems like overkill to add a new method when the old one would
> suffice.  And it would cut down on confusion if this were to be merged
> into the main source.
>
> On Sep 14, 9:32 pm, Sven Fuchs <svenfu...@artweb-design.de> wrote:
>
> > Hi Glenn,
>
> > well, we've been found the same problem while working on Globalize2,  
> > too. Also Yaroslav pointed me to a related problem in his Russian  
> > plugin.
>
> > There's no easy way to hook into the Rails initialization process  
> > right before the Rails frameworks are initialized (which right now  
> > load their translations to the Simple backend).
>
> > We've considered a lot of different approaches to this and in the end  
> > our solution to this is to defer the actual translation loading to the  
> > latest possible point. So clients (like Rails) would only register  
> > translation sources to I18n and the backend would actually lazy-load  
> > them when the first translation needs to be looked up.
>
> > See
>
> >http://github.com/svenfuchs/i18n/tree/master/lib/i18n.rbhttp://github...

Sven Fuchs

unread,
Sep 16, 2008, 7:08:33 AM9/16/08
to rails...@googlegroups.com
Hey Glenn,

On 16.09.2008, at 09:56, glennpow wrote:
> Couldn't it also be just as easy not to have the new load_paths
> method, but instead make the load_translations method perform with
> this same behavior (only to store the paths given)? And then still
> have the first translate call load these paths.
> It seems like overkill to add a new method when the old one would
> suffice. And it would cut down on confusion if this were to be merged
> into the main source.

well, the actual behaviour of the method would change, so it's an API
change anyway :)

As we still haven't released anything (Rails 2.2 is pending) we
believe it's better to name this method in a way so it's less
confusing. With #load_translations one could expect that this
instructs the system to actually load something even if that's not the
case, it only announces a source from where stuff can be loaded.

On 16.09.2008, at 10:41, glennpow wrote:
> On another note, I also found that if you simply have the 'require
> "i18n_backend"' call at the beginning of your 'config/initializers/
> locales.rb' file, and then set the I18n.backend and load your
> translations later in that file, it all seems to work properly.
> Not sure if this breaks Rails protocol (to have a require in an
> initializer), but it works.

I'm not sure what the i18n_backend does in this case, but if you only
change something in your custom initializer that will always mean that
Rails' libraries already were initialized at this point, so the Rails
translations were loaded to the Simple backend.

So assuming that it's not an option to fetch existing translations
from the current backend and re-store them to the new backend when
swapping backends (which might work with the Simple backend being
swapped but will probably be a pain with other backends) ... we either
need to

a - swap the backend before Rails loads or
b - defer the acutal loading of translations to after plugins and
initializers have been run

Option a) would require quite some manual tweeking of requiring the
right things from the right paths because neither the vendorized I18n
gem lib from activesupport would be present nor any backends shipped
as plugins or even gems. Also because Rails does not have any hook for
this we could not provide a "just download the plugin and everything's
already set up" experience, which would work with option b)

As option b) does not seem to have any real drawbacks besides that we
need to pay attention to not load any translations during plugin init
stage when we want to swap the backend afterwards, b) seems like the
most "Rails'ish" solution.

Reply all
Reply to author
Forward
0 new messages