Localization of Rails core

ActionView and ActiveRecord have hardcoded English strings which make using Rails in a different language a bit harder.

ActiveRecord has hardcoded error messages, and ActionView has many helpers rendering English strings, or localized content in English for the US.

Here are some examples:

Date helper: distance_of_time_in_words number_to_currency date_select

FormOptionsHelper: country_options_for_select

Time and Date object

While many plugins monkey patch rails to offer core localization, I feel that we should find a simple localization solution for the core methods with English localization only.

I'm not talking about UI localization or Model localization but simply offering an option to use Rails builtin methods in another context than North America. I'm not trying to fight for a i18n/l10n solution for Rails developers since I know we all have different needs and that's why many people came up with different plugins.

I do understand that this question raises at least 4 issues: - how to deal with pluralization? - how to deal with different grammar and dynamic variables? - how to setup a locale, and what format to adopt? - how to create/maintain core localization?

Here is what I think about the above issues:

Pluralization: At the moment, the core team doesn't use pluralization in their hard coded English strings, and I believe most people would prefer to see a pluralization error instead of an error message in English.

Grammar: The syntax changes from one language to another and you can structure sentences in the same order. I believe it can be easily done by passing one or many variables to the translation.

for instance (inspired by Globalite http://svn.aimonetti.net/public/plugins/globalite/trunk/ ):   :localization_key.translate({:who => 'Matt', :when => 'Time.now'})

The translator could use :when and :when in its translation in whichever order and wherever he wants. (obviously the 'macro' would be replaced by the passed variable)

Locale: Locale is a more touchy subject since if the core lets you define a locale for an user or for the framework, it also mean that most i18n/ l10n plugins will use that same value. However, looking at the actual Rails plugins, none seem to agree on a standard. In Globalite I decided to use the following format (used on a lot of other projects): US English locale would be en-US. Locales are specified by RFC 3066 and consist of two parts. The first is an ISO 639 language code and uses lowercase letters. The second is an ISO 3166 country code in uppercase letters. In the case of Globalite I let the user set only the language and the locale becomes en-* for generic English. This is a personal choice and I'm not sure I would recommend to do the same in the core. I had a discussion with Jeremy Voorhis http://www.jvoorhis.com/ from Globalize during the last RailsConf and agreeing on a standard for a locale might be the only real issue with localizing the core.

Create/maintain core localization: I personally think that localization should be included in the core and maintained by the core team. Obviously they wouldn't be able to translate the core themselves.

My 2 cents worth,

  m>a

+1

I don't want to get into details yet, but I agree that the main issue is agreeing on a standard for view translation that all plugins will have to support. In Globalize, this would be: 'Validation Error'.t, instead of simply 'Validation Error'. The idea would be for Rails core to overload String#t with a method that simply returns the original string, i.e. a no-op. The end user could then choose to use any i18n plugin he wants, and everything would be available for translation with no monkey-patching needed. This in itself would be a huge step, and I don't see a lot of downside. Localizing dates and countries could also be done much the same way.

If we agree that this is a good idea, we can start discussing standardization details.

Josh Harvey Globalize Dev

Most sentences can't be localized with just a word by word translation. I don't think this will solve the problem. I localize by overriding the relevant methods.

Manfred

The end user could then choose to use any i18n plugin he wants, and everything would be available for translation with no monkey-patching needed. This in itself would be a huge step, and I don't see a lot of downside. Localizing dates and countries could also be done much the same way.

I don't quite follow how adding a String#t no-op helps the localization plugins? Could you explain that a bit more please?

I personally think that localization should be included in the core and maintained by the core team. Obviously they wouldn't be able to translate the core themselves.

This has come up repeatedly, and it is unlikely that rails' core will be localised. We only want something there which fits most cases, most of the time. The fact that there are multiple competing implementations and approaches for localising rails applications indicates that there isn't a clear best-practise here yet.

I personally think that localization should be included in the core and maintained by the core team. Obviously they wouldn't be able to translate the core themselves.

This has come up repeatedly, and it is unlikely that rails' core will be localised. We only want something there which fits most cases, most of the time. The fact that there are multiple competing implementations and approaches for localising rails applications indicates that there isn't a clear best-practise here yet.

I'm sorry I wasn't clear enough, I don't want to find a way of localizing rails applications but only localizing the core 'messages'. I fully agree with you Koz, there isn't a clear best-practice and each application will have different needs and can use one of the many available plugin. However, I do believe that one shouldn't have to overwrite the core methods to translate the output of a standard helper.

During the RailsConf, I had the opportunity to discuss this issue with David Heinemeier Hansson and maybe he could explain better the issue and potential solutions?

Matt

Well, each i18n plugin would override String#t to actually translate the validation message. Anybody who doesn't want i18n just uses Rails as usual. But anyone who does want to translate, just adds their localization plugin of choice, which now can automatically translate all of the Rails validation messages without having to alter any core Rails code.

Btw, when I say String#t, I don't mean that it has to be String#t -- it could be any agreed upon stand-in. Also, it could be a bit more sophisticated, to handle pluralization and string interpolation as Globalize currently does.

Hope that helps, Josh

That made sense to me right from the start. It’s crude, but would lift (some of) the pain of plugin authors. There will never be one-size-fits-all anyway.

Well, each i18n plugin would override String#t to actually translate the validation message. Anybody who doesn't want i18n just uses Rails as usual. But anyone who does want to translate, just adds their localization plugin of choice, which now can automatically translate all of the Rails validation messages without having to alter any core Rails code.

But String#t, or anything else, would be entirely redundant without localisation code in rails right? Adding a bunch of method invocations for no new functionality doesn't seem like a good trade :slight_smile:

  It seems the best bet is to leave the concern entirely outside rails itself, until the current disparate efforts can be folded into a single 'best practise'. Failing that, perhaps it's something where there isn't a solution which suits 'most of the people most of the time'.

Is this the opinion of the whole team? That copy/pasting whole code for Rails core methods is the preferred way of changing hardcoded strings?

No wonder i18n plugins always fell behind on new releases of the framework. It’s hard to keep up that way.

  It seems the best bet is to leave the concern entirely outside rails itself, until the current disparate efforts can be folded into a single 'best practise'. Failing that, perhaps it's something where there isn't a solution which suits 'most of the people most of the time'.

There will never be a best practice because there is more than one problem to solve. But does this mean that Rails Core feels that it's OK for a growing number of plugins to override large chunks of Rails code? For this problem 'most people' means 'most il8n plugin developers' and 'people who need localization' of which there are many of both now.

One could look at the 'prepend_view_path' option as a feature that was added specifically to ease the development of plugins. Why would a similar solution for changing error messages and other hard-coded strings in Rails be different,   except for the valid point of having extra (though hardly complex or detrimental) method invocations?

It's understandable to shy away from il8n because of its 'can of worms' nature. But what we're really talking about here   is providing a simple mechanism by which plugins can access and change Rails error messages and hard-coded strings. Lumping that in with the rest of the il8n/il0n problems is a red herring.

Perhaps it's time to lift the stigma associated with il8n and look at a specific proposal for how to solve this. Many other frameworks provide simple solutions to this without adding complexity beyond variable interpolation.

Joshua Sierles

Michael Koziarski wrote:

Well, each i18n plugin would override String#t to actually translate the validation message. Anybody who doesn't want i18n just uses Rails as usual. But anyone who does want to translate, just adds their localization plugin of choice, which now can automatically translate all of the Rails validation messages without having to alter any core Rails code.

But String#t, or anything else, would be entirely redundant without localisation code in rails right? Adding a bunch of method invocations for no new functionality doesn't seem like a good trade :slight_smile:

It would make the life of all non-english developers a lot easier as swapping the hard coded strings becomes very easy and does not include copy&pasting functionality or fiddling rails' internals.

In case of the average english developer nothing has changed.

Jonathan

Agreed 100%. The fact that localization plugins have to override many hard coded strings in core Rails points to a problem with core Rails, and not an issue with localization complexity. This is just a 'better practices' thing - externalize constants so they can be easily changed, whether for language or just preference.

International apps shouldn't be penalized just because the core team writes English-only apps. There should be a easier solution to allow overriding the default messages, while maintaining the English messages for the 80% who are fine with that.

Are there any patches in trac that address this problem directly?

- Rob

Is it possible to auto-extract strings like Heckle? Doing so it would be very easy to lookup for translatable strings and no change to core would be needed.

Marcello

Is it possible to auto-extract strings like Heckle? Doing so it would be very easy to lookup for translatable strings and no change to core would be needed.

Marcello

Is it possible to auto-extract strings like Heckle? Doing so it would be very easy to lookup for translatable strings and no change to core would be needed.

Marcello

Is it possible to auto-extract strings like Heckle? Doing so it would be very easy to lookup for translatable strings and no change to core would be needed.

Marcello

I understand that many people won't get use out of 't', but I think the extra work involved (we're talking about an extra charcter, and letting the people who care submit patches to clean up what's already there) is trivial in comparison to what is gained here. It means that i18n efforts can hook into rails core easily, without monkey patching large bits of code (which is inhearently error prone).

I think this fits into something that has minimal effect on the codebase at large, but has a very large gain for the plugin writing community. I think this effort, which isn't deciding on a specific way to do i18n, but only on a common helper method for it, is something core can do without picking sides. I also think this means that the arguments about localization of rails core are going to go away because people can solve their own problems easily.

Wouldn't that be nice? No more threads about localization in rails core? Wouldn't it? :wink:

Kev

Alright, that's exactly what I wanted to avoid... a long thread about how the core should deal with localization :frowning:

I don't think the core team should adopt a .t method or another way of dealing with translation. That's really up to the plugin developers to decide. What I would like to see is simply a way of declaring your locale and when you call one of the usual method, instead of returning an English string you get something in your own language/culture.

Nothing fancy, nothing specially designed to help l10n/i18n plugins but just to avoid patching the core methods. (extending is fine)

-Matt

Nothing fancy, nothing specially designed to help l10n/i18n plugins but just to avoid patching the core methods. (extending is fine)

Provided there are no adverse performance or understandability impacts, I think we could apply a patch which refactored the core code a little. If a little bit of refactoring would let plugin authors override in a slightly-more-surgical manner, then I figure that'll add much more to l10n plugin authors than a no-op, uncalled, method on String. :slight_smile: