A problem arises when you use I18N plugins (or your own code) to localize web sites; the data derived from your database is not localized. You have several options:
First of all, create a table to hold the values you need to localize (such as name, notes, etc).
That table should have a field like 'locale' (or an id pointing to a list of available locales). This way you avoid adding new columns for every language you have to support in the future.
Of course, that table should contain a reference to the id of its main data (i.e. the table you want to localize). For convention we use 'local_entities' to localize a table of 'entities'.
Then you go to the model class you wish to localize and add the following:
'locale' is now a class variable you can set from any controller simply. For best results, use in a before filter in your application controller.
You now have to ensure that you localizations are fetched every time you call Entity.find. Of course there is considerable oversizing of requested data (if you have that many locales to support and a large dataset to return) but the performance hit is not that huge using :include. Why? Because having to fetch localization for every record being displayed can affect performance much more.
This works best for one or two alternative languages being supported on large datasets. More elegant code can be written to further optimize the data fetched, if you find any, please tell us.
The above functions return localized strings if they are defined and fall back to the original (default) language if none is found. This guarantees at least some valid string to be displayed.
So, just use entity_instance.name when you need to get the default name and entity_instance.localname when you need a safe means of displaying localized text.
Enjoy.
- You can give up on international users.
- You can use another plugin to 'Globalize' your database.
- You can do it yourself.
First of all, create a table to hold the values you need to localize (such as name, notes, etc).
That table should have a field like 'locale' (or an id pointing to a list of available locales). This way you avoid adding new columns for every language you have to support in the future.
Of course, that table should contain a reference to the id of its main data (i.e. the table you want to localize). For convention we use 'local_entities' to localize a table of 'entities'.
Then you go to the model class you wish to localize and add the following:
class Entity < ActiveRecord::Base cattr_accessor :locale has_many :local_entities
'locale' is now a class variable you can set from any controller simply. For best results, use in a before filter in your application controller.
before_filter :set_locale
def set_locale
Entity.locale = session[:locale] || 'en-US'
end
You now have to ensure that you localizations are fetched every time you call Entity.find. Of course there is considerable oversizing of requested data (if you have that many locales to support and a large dataset to return) but the performance hit is not that huge using :include. Why? Because having to fetch localization for every record being displayed can affect performance much more.
This works best for one or two alternative languages being supported on large datasets. More elegant code can be written to further optimize the data fetched, if you find any, please tell us.
def self.find(*args)
self.with_scope(:find => {:order => :name, :include => 'local_entities'}) {
super
}
end
def localname
local = self.local_entities.first(:conditions => "locale_code = '#{locale}'")
return (local.nil?) ? self.name : local.name
end
def localnotes
local = self.local_entities.first(:conditions => "locale_code = '#{locale}'")
return (local.nil?) ? self.notes : local.notes
end
The above functions return localized strings if they are defined and fall back to the original (default) language if none is found. This guarantees at least some valid string to be displayed.
So, just use entity_instance.name when you need to get the default name and entity_instance.localname when you need a safe means of displaying localized text.
Enjoy.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.