Skip to content
Browse files

New and improved. Now With a README

  • Loading branch information...
1 parent 20ed785 commit a35703d5eca656f75b610376200c1c6865c4b97a @glennpow committed
Showing with 154 additions and 42 deletions.
  1. +100 −4 README
  2. +6 −6 lib/localized_record/backend.rb
  3. +3 −3 lib/localized_record/base.rb
  4. +45 −29 lib/localized_record/helper.rb
View
104 README
@@ -1,13 +1,109 @@
LocalizedRecord
==============
-Introduction goes here.
+This plugin gives ActiveRecord objects the ability to have localized attributes. This is similar to what the
+Globalize2 plugin does, however, LocalizedRecord doesn't require any modifications to the database.
+It utilizes a simple String column in the DB, and determines if this value is meant to be localized or not based
+on the mode that the plugin is set to.
+Install
+-------
-Example
-=======
+Install this plugin, by running this from your Rails application's root directory:
-Example goes here.
+ script/plugin git://github.com/glennpow/localized_record.git
+
+
+Setup
+-----
+
+First you can set the global default mode and available locales in an initializer as follows:
+
+ LocalizedRecord.mode = :tsv
+ LocalizedRecord.available_locales = [ 'en', 'es' ]
+
+Then, to add the functionality to an ActiveRecord model, add a line in the class similar this:
+
+ class Message < ActiveRecord::Base
+ has_localized :name, :description
+ end
+
+The method takes a list of attribute names which it will operate on for this model class. Alternatively, without
+any attribute names, the method will search for all 'string' and 'text' columns, and operate on those.
+
+You can also specify a mode specifically for this ActiveRecord model class:
+
+ has_localized :name, :description, :mode => :tsv
+
+
+Usage
+-----
+
+Now, any time you access any of those attributes of a model of that class, it will check if the value is a localized
+String, then look at the current locale (I18n.locale, I18n.default_locale, or user-specified), and then return
+the proper translation.
+
+So if a model has 2 translations for it's name, one for English and one for German, and the current I18n.locale is set
+to 'de', then calling:
+
+ Message.first.name
+
+Will return:
+
+ "Hallo und Wilkommen"
+
+Or calling:
+
+ Message.first.name(:locale => 'en')
+
+Will return:
+
+ "Hello and Welcome"
+
+
+Template Usage
+--------------
+
+There is also an ERB helper which will create text fields or text areas for your localized attributes.
+You can add them by first adding a localization select drop down (which when changed, will hide/show the fields
+for the selected locale):
+
+ <%= localization_select %>
+
+And then adding (Where 'f' is either a FormBuilder object or an ActiveRecord object):
+
+ <%= localized_text_field(f, :name) %>
+ <%= localized_text_area(f, :description) %>
+
+This will create all the fields you need to enter values for these attributes in each of the available_locales.
+
+
+Notes on Implementation
+-----------------------
+
+I attempted to build the plugin to be compatible with the I18n functionality now found in Rails. I also originally
+envisioned the plugin to have custom "backends" in the same manner as the I18n. However, I have since postponed/scrapped
+this idea in light of the fact that some DB tables may want to use different modes, so one single backend shouldn't
+necessarily be set for an application.
+
+The present "backend" does have different modes, which can and will be enhanced as time goes on. Currently, the only fully
+supported mode is :tsv (Tab-separated values). This mode will put translations into the string column of a record as follows:
+
+"en\tHello and Welcome\tde\tHallo und Wilkommen"
+
+Where the "\t" are tab characters, and the format is locale, value, locale, value,...
+
+The backend can also intelligently check if the current value in the column should be handled as a translation using
+the 'localized?' method. For the :tsv mode, this check simply looks if there are any tabs in the String.
+If there is a non-tabbed String in this column, then this value is treated like any other non-localized String
+column value in Rails.
+
+
+Development Note
+----------------
+
+Please note that this plugin is very new, and still under development. But any feedback will be greatly appreciated.
+Thanks.
Copyright (c) 2009 Glenn Powell, released under the MIT license
View
12 lib/localized_record/backend.rb
@@ -1,13 +1,13 @@
require 'libxml'
module LocalizedRecord
- mattr_accessor :mode, :supported_locales
+ mattr_accessor :mode, :available_locales
self.mode = :tsv
- self.supported_locales = [ I18n.default_locale.to_s, 'es' ]
+ self.available_locales = [ I18n.default_locale.to_s, 'es' ]
- def supported_modes
- [ :tsv, :tmx ]
+ def available_modes
+ [ :tsv ] # TODO ... , :tmx ]
end
def self.localized?(value, mode = nil)
@@ -25,7 +25,7 @@ def self.localized?(value, mode = nil)
end
end
- def self.parse(value, mode = nil)
+ def self.s_to_translations(value, mode = nil)
mode ||= LocalizedRecord.mode
case mode
@@ -52,7 +52,7 @@ def self.parse(value, mode = nil)
end
end
- def self.compile(translations, mode = nil)
+ def self.translations_to_s(translations, mode = nil)
mode ||= LocalizedRecord.mode
case mode
View
6 lib/localized_record/base.rb
@@ -26,7 +26,7 @@ def has_localized(*args)
locale = (options[:locale] || I18n.locale).to_s
begin
- translations = LocalizedRecord.parse(value, mode)
+ translations = LocalizedRecord.s_to_translations(value, mode)
rescue ArgumentError => e
raise InvalidTranslationValue.new(locale, self, attribute, value, options)
end
@@ -47,7 +47,7 @@ def has_localized(*args)
end
define_method "#{attribute}=" do |value|
- value = LocalizedRecord.compile(value, self.class.localized_mode) if value.is_a?(Hash)
+ value = LocalizedRecord.translations_to_s(value, self.class.localized_mode) if value.is_a?(Hash)
super(value)
end
end
@@ -83,7 +83,7 @@ def initialize(record = nil, attribute = nil, default_locale = nil)
default_locale = (default_locale || I18n.default_locale).to_s
value = record.send(attribute)
if LocalizedRecord.localized?(value, mode)
- @translations = LocalizedRecord.parse(value, mode)
+ @translations = LocalizedRecord.s_to_translations(value, mode)
else
@translations[default_locale] = value
end
View
74 lib/localized_record/helper.rb
@@ -1,15 +1,15 @@
module LocalizedRecord
module Helper
- def localized_select(options = {})
- locales = (options.delete(:locales) || LocalizedRecord.supported_locales).map(&:to_s)
+ def localization_select(options = {})
+ locales = (options.delete(:locales) || LocalizedRecord.available_locales).map(&:to_s)
default_locale = (options.delete(:default_locale) || I18n.default_locale).to_s
select_options = options.merge(:onchange => "$$('.localized-field').invoke('hide'); $$('.localized-field-' + this.options[this.selectedIndex].value).invoke('show')")
- select_tag("localized_select", options_for_select(locales.map { |locale| [ locale, locale ] }, default_locale), select_options)
+ select_tag("localization_select", options_for_select(locales.map { |locale| [ locale, locale ] }, default_locale), select_options)
end
- def localized_text_field(form_or_record, method, options = {})
- locales = (options.delete(:locales) || LocalizedRecord.supported_locales).map(&:to_s)
+ def localized_fields_for(form_or_record, method, options = {}, &block)
+ locales = (options.delete(:locales) || LocalizedRecord.available_locales).map(&:to_s)
default_locale = (options.delete(:default_locale) || I18n.default_locale).to_s
record = case form_or_record
when ActionView::Helpers::FormBuilder
@@ -24,38 +24,54 @@ def localized_text_field(form_or_record, method, options = {})
case form_or_record
when ActionView::Helpers::FormBuilder
form_or_record.fields_for(method, proxy) do |f|
- locales.each do |locale|
- display = (locale == default_locale) ? "block" : "none"
- text_field_options = {}
- options.each do |key, value|
- if value.is_a?(Proc)
- text_field_options[key] = value.call(locale)
- else
- text_field_options[key] = value
- end
- end
- concat(content_tag(:div, f.text_field(locale, text_field_options), :class => "localized-field localized-field-#{locale}", :style => "display: #{display}"))
- end
+ locales_for_localized_field(f, locales, default_locale, &block)
end
else
fields_for(form_or_record, method, proxy) do |f|
- locales.each do |locale|
- display = (locale == default_locale) ? "block" : "none"
- text_field_options = {}
- options.each do |key, value|
- if value.is_a?(Proc)
- text_field_options[key] = value.call(locale)
- else
- text_field_options[key] = value
- end
- end
- concat(content_tag(:div, f.text_field(locale, text_field_options), :class => "localized-field localized-field-#{locale}", :style => "display: #{display}"))
- end
+ locales_for_localized_field(f, locales, default_locale, &block)
end
end
output_buffer
end
end
+
+ def localized_text_field(form_or_record, method, field_options = {}, localized_options = {})
+ localized_fields_for(form_or_record, method, localized_options) do |f, locale|
+ localized_field_options = {}
+ field_options.each do |key, value|
+ case value
+ when Proc
+ localized_field_options[key] = value.call(locale)
+ else
+ localized_field_options[key] = value
+ end
+ end
+ f.text_field(locale, localized_field_options)
+ end
+ end
+
+ def localized_text_area(form_or_record, method, field_options = {}, localized_options = {})
+ localized_fields_for(form_or_record, method, localized_options) do |f, locale|
+ localized_field_options = {}
+ field_options.each do |key, value|
+ case value
+ when Proc
+ localized_field_options[key] = value.call(locale)
+ else
+ localized_field_options[key] = value
+ end
+ end
+ f.text_area(locale, localized_field_options)
+ end
+ end
+
+ def locales_for_localized_field(form, locales, default_locale, &block)
+ locales.each do |locale|
+ display = (locale == default_locale) ? "block" : "none"
+ content = block_called_from_erb?(block) ? capture(form, locale, &block) : yield(form, locale)
+ concat(content_tag(:div, content, :class => "localized-field localized-field-#{locale}", :style => "display: #{display}"))
+ end
+ end
end
end

0 comments on commit a35703d

Please sign in to comment.
Something went wrong with that request. Please try again.