Am I doing it right? (translating my first app)

121 views
Skip to first unread message

Redd Vinylene

unread,
Oct 2, 2008, 1:14:47 PM10/2/08
to rails...@googlegroups.com
Hello hello! I just finished translating my app, however my
translations won't load. So first, what am I doing wrong? And second,
is there anything that can be done better? I'm a bit confused since
every tutorial and demo app seems to have its own way of doing things.
Alright, that's it. Thanks everyone!

/myapp
/myapp/lang
/myapp/lang/en
/myapp/lang/en/en.yml
/myapp/lang/en/en_about.yml
/myapp/lang/en/en_app.yml
/myapp/lang/is/is.yml
/myapp/lang/is/is_about.yml
/myapp/lang/is/is_app.yml

## /myapp/config/environment.rb

I18n.default_locale = "en"

LOCALES_DIRECTORY = "#{RAILS_ROOT}/lang/"

LOCALES_AVAILABLE = Dir["#{LOCALES_DIRECTORY}/*/*.yml"].collect do |locale_file|
File.basename(locale_file, ".yml")
end.uniq

## /myapp/app/controllers/application.rb

before_filter :set_locale

def set_locale
I18n.locale = params[:locale] if params[:locale]
end

## /myapp/app/helpers/application_helper.rb

def t(*args)
translate(*args)
end

## /myapp/app/views/admin/preferences/edit.html.erb

<%= f.label "locale", t(:"locale") %><%= f.select("locale",
options_for_select(LOCALES_AVAILABLE, I18n.locale) %>

--
http://www.home.no/reddvinylene

Iain Hecker

unread,
Oct 2, 2008, 3:01:56 PM10/2/08
to rails...@googlegroups.com
Hi,

You're missing a few parts. First is the loading of the files into
I18n. Put this into your environment:

I18n.load_translations(*Dir.glob(LOCALES_DIRECTORY+'/**/*.yml'))

look here how to get available_locales:
http://rails-i18n.org/wiki/pages/i18n-available_locales (put it in an
initializer)

Secondly, you need to set the proper locale at every request, so in
your before_filter you need to default to the locale stored in the
user's session or from preferences stored in the database.

def set_locale
I18n.locale = params[:locale] or session[:locale] or I18n.default_locale
session[:locale] = I18n.locale
end

Hope this helps,

Iain

iain hecker

unread,
Oct 2, 2008, 3:16:57 PM10/2/08
to rails-i18n
Wait, there has been some change. Read this:
http://groups.google.com/group/rails-i18n/t/103b9c555b6fb54e?hl=en

In environment it should read something like I18n.load_path =
RAILS_ROOT + '/lang'

I haven't tried it before.


On Oct 2, 9:01 pm, "Iain Hecker" <i...@iain.nl> wrote:
> Hi,
>
> You're missing a few parts. First is the loading of the files into
> I18n. Put this into your environment:
>
> I18n.load_translations(*Dir.glob(LOCALES_DIRECTORY+'/**/*.yml'))
>
> look here how to get available_locales:http://rails-i18n.org/wiki/pages/i18n-available_locales(put it in an
> initializer)
>
> Secondly, you need to set the proper locale at every request, so in
> your before_filter you need to default to the locale stored in the
> user's session or from preferences stored in the database.
>
> def set_locale
>   I18n.locale = params[:locale] or session[:locale] or I18n.default_locale
>   session[:locale] = I18n.locale
> end
>
> Hope this helps,
>
> Iain
>

Redd Vinylene

unread,
Oct 3, 2008, 5:34:28 AM10/3/08
to rails...@googlegroups.com
On Thu, Oct 2, 2008 at 9:16 PM, iain hecker <ia...@iain.nl> wrote:
>
> Wait, there has been some change. Read this:
> http://groups.google.com/group/rails-i18n/t/103b9c555b6fb54e?hl=en
>
> In environment it should read something like I18n.load_path =
> RAILS_ROOT + '/lang'
>
> I haven't tried it before.

Thanks a lot man for this wonderful advice. I'll give it a go and report back.

Maybe it's just me but isn't module Backend in
http://rails-i18n.org/wiki/pages/i18n-available_locales missing an
end?

--
http://www.home.no/reddvinylene

Iain Hecker

unread,
Oct 3, 2008, 6:45:58 AM10/3/08
to rails...@googlegroups.com
It does...

Karel Minarik

unread,
Oct 3, 2008, 8:51:33 AM10/3/08
to rails-i18n
Hello Iain,

*please* don't advise people to use `session` for setting locale! That
is an unfortunate choice by the official i18n demo app and completely
breaks RESTfullnes of anything. (ie. completely breaks even such
simple thing like sending someone a URL and expecting that she'll see
the same thing.)

One should set locale from params, hostname, accepted-language header,
whatever, just *not* session.


Karel

On Oct 2, 9:01 pm, "Iain Hecker" <i...@iain.nl> wrote:
> Hi,
>
> You're missing a few parts. First is the loading of the files into
> I18n. Put this into your environment:
>
> I18n.load_translations(*Dir.glob(LOCALES_DIRECTORY+'/**/*.yml'))
>
> look here how to get available_locales:http://rails-i18n.org/wiki/pages/i18n-available_locales(put it in an
> initializer)
>
> Secondly, you need to set the proper locale at every request, so in
> your before_filter you need to default to the locale stored in the
> user's session or from preferences stored in the database.
>
> def set_locale
>   I18n.locale = params[:locale] or session[:locale] or I18n.default_locale
>   session[:locale] = I18n.locale
> end
>
> Hope this helps,
>
> Iain
>

Iain Hecker

unread,
Oct 3, 2008, 9:50:38 AM10/3/08
to rails...@googlegroups.com
I see your point. How do you maintain the chosen locale? If the locale
comes from the params, it doesn't only produce ugly urls, but you also
need some way to add it to every link you generate. There is no
elegant solution for this at the moment.

The other option is using the hostname (i.e. a subdomain), but you're
not always able to use this (if you're not the only website on one
domain or if you're using https with a valid certificate).

I'd love to hear some advice.

What seems to me an elegant solution is some routes work:

map.with_options :path_prefix => '/:locale' do |localized|
localized.resources :projects
end

It seems nice, but how to fill the locale with the currently selected
locale? I don't like to do this all the time: projects_path(:locale =>
I18n.locale)

Rails seems to have an answer to it, called default_url_options[1],
but it doesn't seem to work. I've overwritten the method like the api
tells me, but somehow it is ignored into generating the path. It is
called, because it will break if I raise somthing in it. The options
passed to it are what you'd expect (containing all the parameters
you'd pass to url_for)

Here's my method:

def default_url_options(options = {})
{ :locale => I18n.locale }
end

While typing this message I found something perculiar. It only happens
with new_post_path and posts_path in my own little example (without
the route described above).

I have a scaffolded view and when in index the edit/delete and show
links all get the parameter properly, but not the new and index links.
Why not those two? The only difference I found between those two and
the rest is that new and index don't use params[:id].

Furthermore, I found that if I use the route I specified above, the
post object gets assigned to the locale-param. This results in an
error like:

edit_post_url failed to generate from {:action=>"edit",
:locale=>#<Post id: 1, title: "Foo", etc...

What is going on?

[1] http://api.rubyonrails.com/classes/ActionController/Base.html#M000851

Raul Murciano

unread,
Oct 3, 2008, 9:54:22 AM10/3/08
to rails...@googlegroups.com
2008/10/3 Iain Hecker <ia...@iain.nl>:

>
> I see your point. How do you maintain the chosen locale? If the locale
> comes from the params, it doesn't only produce ugly urls, but you also
> need some way to add it to every link you generate. There is no
> elegant solution for this at the moment.

<shameless-self-promotion>
http://github.com/raul/translate_routes/tree/master
</shameless-self-promotion>

--
Raul Murciano - Freelance Web Developer
http://raul.murciano.net

Karel Minarik

unread,
Oct 3, 2008, 12:44:14 PM10/3/08
to rails-i18n
Hi Iain,

> I see your point.

well, I think the REST principle: "every resource represenatation
should be identifiable by an unique URL" is really something one
should *never, ever* break. It is the backbone of internet. (And
probably everyone of us saw some unbelievably ugly .NET/PHP/etc apps
which are totally broken in this sense. The bigger the app, the worse,
usually.)

> How do you maintain the chosen locale? If the locale
> comes from the params, it doesn't only produce ugly urls, but you also
> need some way to add it to every link you generate.

Yes, that is true. Usually it is done by prefixing the locale in URL (/
en/some/resource, /es/some/resource) and people are really used to it.
Raul's solutions looks very nice.

> The other option is using the hostname (i.e. a subdomain), but you're
> not always able to use this (if you're not the only website on one
> domain or if you're using https with a valid certificate).

Yes, I like the hostname option very much (meaning application.com vs
application.de, etc), and it is a preferred way now for me for content-
oriented projects. I did it like that in the demo app and provided
guide how to setup it locally with /etc/hosts. As stated in the demo
app README, search engines love this separation as well (for obvious
reasons).

Of course, there are edge cases, where it's tricky.

> Rails seems to have an answer to it, called default_url_options[1],

Wow, I didn't knew about it, guess Rails is really stretched now. This
would be of course *absolutely* awesome, because it could solve the
most trivial scenario: prefixing locale into every URL, and do that
transparently. This is something we should investigate. Could you
submit a ticket at Lightouse about this?

Redd Vinylene

unread,
Oct 4, 2008, 7:20:09 AM10/4/08
to rails...@googlegroups.com
On Fri, Oct 3, 2008 at 2:51 PM, Karel Minarik <karel....@gmail.com> wrote:
>
> Hello Iain,
>
> *please* don't advise people to use `session` for setting locale! That
> is an unfortunate choice by the official i18n demo app and completely
> breaks RESTfullnes of anything. (ie. completely breaks even such
> simple thing like sending someone a URL and expecting that she'll see
> the same thing.)
>
> One should set locale from params, hostname, accepted-language header,
> whatever, just *not* session.

How? Like this?

def set_locale
I18n.locale = params[:locale] if params[:locale]
end

--
http://www.home.no/reddvinylene

Karel Minarik

unread,
Oct 5, 2008, 5:09:16 AM10/5/08
to rails-i18n
> How? Like this?
>
> def set_locale
>  I18n.locale = params[:locale] if params[:locale]
> end

Or like this....

http://github.com/karmi/rails_i18n_demo_app/tree/master/app/controllers/application.rb#L12-15

Karel

Geoffroy Gomet

unread,
Oct 5, 2008, 6:58:07 AM10/5/08
to rails-i18n
Hello Redd,

Could you please explain how using the session to store the preferred
language is going against 'RESTfullnes'.
Someone copying and pasting an url would just see the page in the
default language, not really a problem there, except choosing the
right language.
If you advise to pass the language in the url everytime, I think it
would be against the clean url Rails produces.

I think in the long time, you could find yourself with very cluttered
urls full of parameters, which would be a big step back.

Geoffroy Gomet


On Oct 4, 1:20 pm, "Redd Vinylene" <reddvinyl...@gmail.com> wrote:

Sven Fuchs

unread,
Oct 5, 2008, 7:05:39 AM10/5/08
to rails...@googlegroups.com

Sven Fuchs

unread,
Oct 5, 2008, 7:08:30 AM10/5/08
to rails...@googlegroups.com
*arrrgh*

I wanted to say:

> On 03.10.2008, at 14:51, Karel Minarik wrote:
>> *please* don't advise people to use `session` for setting locale!
>> That

I agree.

>> is an unfortunate choice by the official i18n demo app and completely
>> breaks RESTfullnes of anything.

Which one? where? something we need to correct?

Sven Fuchs

unread,
Oct 5, 2008, 7:14:51 AM10/5/08
to rails...@googlegroups.com
Geoffroy,

sessions are not restful by the definition of rest :)

Storing a locale in the session of a client means that state is stored
on the clientside. The simple test for this aspect of rest probably
is: if you can copy and paste the URL to an email, send it off to a
buddy and be sure that your buddy will see the same page as you're
looking at ... then that's ok. If he sees a different page, it's not.

To me displaying a page in an entirely different language means that
it's a "different" page, so I agree with Karel that we definitely
should not advise peopel to use the session for this.

Instead, use subdomains, parts of the path or even query params for
that. Even though it's more work or might look ugly, it does not break
the internet ;)

As for the "more work" part, when it comes to locales as path
segments: that's a question of better support in Rails. Raul already
plugged his solution, so lemme add mine:

<shameless-self-promotion>
http://github.com/svenfuchs/routing-filter
</shameless-self-promotion>

Geoffroy Gomet

unread,
Oct 6, 2008, 2:16:23 AM10/6/08
to rails-i18n
Hello Sven,

Thank you for the explanation, it's always nice to read crystal clear
explanation.
I did thought of including the language in the route, but then again,
thought about extremely long url.

But now I understand why you advice not to use the session.

Thanks a lot

Geoffroy

Karel Minarik

unread,
Oct 6, 2008, 5:59:20 AM10/6/08
to rails-i18n
Hi Sven,

> >> is an unfortunate choice by the official i18n demo app and completely
> >> breaks RESTfullnes of anything.
> Which one? where? something we need to correct?

Still there: http://github.com/clemens/i18n_demo_app/tree/master/app/controllers/application.rb#L23

Karel

Redd Vinylene

unread,
Oct 7, 2008, 8:18:59 AM10/7/08
to rails...@googlegroups.com, ia...@iain.nl, karel....@gmail.com, geoffro...@gmail.com, sven...@artweb-design.de
Okay guys, here's the latest. I hope I've got it right this time.

Also:

1. Will I (in Preferences#edit) be able to choose locale from a select
box, like in Clemens Kofler's demo? I don't think I need any of that
URL stuff. I just want it plain and simple, one language only.

2. Is the organization of my locales proper? Or must en.yml,
en_about.yml and en_app.yml be put into a single file for the
Preferences#edit select box to work?

The following is also available at http://pastie.org/286698

/myapp
/myapp/app/controllers/application.rb
/myapp/app/helpers/application_helper.rb
/myapp/app/views/admin/preferences/edit.html.erb
/myapp/config/environment.rb
/myapp/config/initializers/i18n.rb


/myapp/lang
/myapp/lang/en
/myapp/lang/en/en.yml
/myapp/lang/en/en_about.yml
/myapp/lang/en/en_app.yml
/myapp/lang/is/is.yml
/myapp/lang/is/is_about.yml
/myapp/lang/is/is_app.yml

## /myapp/config/environment.rb

I18n.load_path = RAILS_ROOT + "/lang"

I18n.default_locale = "en"

## /myapp/config/initializers/i18n.rb

module I18n
class << self
def available_locales
backend.available_locales
end
end

module Backend
class Simple
def available_locales
translations.keys
end
end
end
end

## /myapp/app/controllers/application.rb

before_filter :set_locale

def set_locale
I18n.locale = extract_locale_from_params || "en"
end

## /myapp/app/helpers/application_helper.rb

def t(*args)
translate(*args)
end

## /myapp/app/views/admin/preferences/edit.html.erb

<%= f.label "locale", t(:"locale") %><%= f.select("locale",

options_for_select(I18n.available_locales) %>

--
http://www.home.no/reddvinylene

Save The Vinyls

unread,
Oct 20, 2008, 10:36:15 AM10/20/08
to rails-i18n
Short answer is NO, you are NOT doing it right.

You do not need to put anything into application.rb.

environment.rb needs only this:

I18n.load_path = Dir.glob("#{RAILS_ROOT}/lang/**/*.yml")
I18n.default_locale = "en"

On Oct 7, 2:18 pm, "Redd Vinylene" <reddvinyl...@gmail.com> wrote:
> Okay guys, here's the latest. I hope I've got it right this time.
>
> Also:
>
> 1. Will I (in Preferences#edit) be able to choose locale from a select
> box, like in Clemens Kofler's demo? I don't think I need any of that
> URL stuff. I just want it plain and simple, one language only.
>
> 2. Is the organization of my locales proper? Or must en.yml,
> en_about.yml and en_app.yml be put into a single file for the
> Preferences#edit select box to work?
>
> The following is also available athttp://pastie.org/286698
Reply all
Reply to author
Forward
0 new messages