embedded_localization 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.textile +214 -0
- data/Rakefile +1 -0
- data/embedded_localization.gemspec +29 -0
- data/lib/embedded_localization.rb +17 -0
- data/lib/embedded_localization/active_record.rb +7 -0
- data/lib/embedded_localization/active_record/act_macro.rb +65 -0
- data/lib/embedded_localization/active_record/class_methods.rb +24 -0
- data/lib/embedded_localization/active_record/instance_methods.rb +102 -0
- data/lib/embedded_localization/version.rb +3 -0
- data/lib/extensions/hash.rb +7 -0
- metadata +69 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.textile
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
h1. Embedded Localization
|
2
|
+
|
3
|
+
Embedded_Localization is a Rails 3 localization gem, targeted at ActiveRecord 3. It is compatible with and builds on the new "I18n API in Ruby on Rails":http://guides.rubyonrails.org/i18n.html and adds model translations to ActiveRecord.
|
4
|
+
|
5
|
+
Embedded_Localization is very lightweight, and allows you to transparently store translations of attributes right inside each record -- no extra database tables needed to store the localization data! Make sure that your database default encoding is UTF-8 or UFT-16.
|
6
|
+
|
7
|
+
Model translations with Embedded_Localization use default ActiveRecord features and do not limit any ActiveRecord functionality.
|
8
|
+
|
9
|
+
|
10
|
+
h2. Requirements
|
11
|
+
|
12
|
+
ActiveRecord > 3.0.0.rc
|
13
|
+
I18n
|
14
|
+
|
15
|
+
h2. Installation
|
16
|
+
|
17
|
+
To install Embedded_Localization, use:
|
18
|
+
|
19
|
+
<pre><code>
|
20
|
+
$ gem install embedded_localization
|
21
|
+
|
22
|
+
</code></pre>
|
23
|
+
|
24
|
+
h2. Model translations
|
25
|
+
|
26
|
+
Model translations allow you to translate your models' attribute values. The attribute type needs to be string or text, and you need to generate the database fields as usual with ActiveRecord database migrations. e.g.:
|
27
|
+
|
28
|
+
<font color='red'>Note for version <0.2.0:</font> do not define the attributes in the DB migration, but define one text field :i18n for each table which uses Embedded_Localization
|
29
|
+
|
30
|
+
<pre><code>
|
31
|
+
class Genre < ActiveRecord::Base
|
32
|
+
translates :name, :description
|
33
|
+
end
|
34
|
+
|
35
|
+
</code></pre>
|
36
|
+
|
37
|
+
This allows you to translate the attributes :name and :description per locale:
|
38
|
+
|
39
|
+
<pre><code>
|
40
|
+
I18n.locale = :en
|
41
|
+
g = Genre.first
|
42
|
+
g.name # => 'science fiction'
|
43
|
+
|
44
|
+
I18n.locale = :jp
|
45
|
+
g.name # => "サイエンスフィクション"
|
46
|
+
|
47
|
+
I18n.locale = :ko
|
48
|
+
g.name # => "공상 과학 소설"
|
49
|
+
</code></pre>
|
50
|
+
|
51
|
+
No extra tables needed for this!
|
52
|
+
|
53
|
+
h3. Rails 3.0
|
54
|
+
|
55
|
+
<pre><code>
|
56
|
+
class CreateGenres < ActiveRecord::Migration
|
57
|
+
def self.up
|
58
|
+
create_table :genres do |t|
|
59
|
+
t.string :name
|
60
|
+
t.text :description
|
61
|
+
t.timestamps
|
62
|
+
end
|
63
|
+
end
|
64
|
+
def self.down
|
65
|
+
drop_table :posts
|
66
|
+
end
|
67
|
+
end
|
68
|
+
</code></pre>
|
69
|
+
|
70
|
+
Note that the ActiveRecord model @Genre@ must already exist and have a @translates@ directive listing the translated fields.
|
71
|
+
|
72
|
+
h3. Rails 3.0 + Embedded_Localization version < 0.2.0
|
73
|
+
|
74
|
+
<pre><code>
|
75
|
+
class CreateGenres < ActiveRecord::Migration
|
76
|
+
def self.up
|
77
|
+
create_table :genres do |t|
|
78
|
+
t.text :i18n # this will be deprecated in 0.2.0
|
79
|
+
t.timestamps
|
80
|
+
end
|
81
|
+
end
|
82
|
+
def self.down
|
83
|
+
drop_table :posts
|
84
|
+
end
|
85
|
+
end
|
86
|
+
</code></pre>
|
87
|
+
|
88
|
+
Please note, if you use Embedded_Localization with version < 0.2.0, that you should not define the translated attributes in the migrations -- instead define one text attribute with the name :i18n -- this will change in version 0.2.0
|
89
|
+
|
90
|
+
h2. I18n fallbacks for empty translations
|
91
|
+
|
92
|
+
It is possible to enable fallbacks for empty translations. It will depend on the configuration setting you have set for I18n translations in your Rails config.
|
93
|
+
|
94
|
+
You can enable them by adding the next line to @config/application.rb@ (or only @config/environments/production.rb@ if you only want them in production)
|
95
|
+
|
96
|
+
<pre><code>config.i18n.fallbacks = true</code></pre>
|
97
|
+
|
98
|
+
By default, Embedded_Localization will only use fallbacks when the translation value for the item you've requested is @nil@.
|
99
|
+
|
100
|
+
<pre><code>
|
101
|
+
class Genre < ActiveRecord::Base
|
102
|
+
translates :name, :description
|
103
|
+
end
|
104
|
+
|
105
|
+
I18n.locale = :en
|
106
|
+
g = Genre.first
|
107
|
+
g.name # => 'science fiction'
|
108
|
+
|
109
|
+
I18n.locale = :jp
|
110
|
+
g.name # => "サイエンスフィクション"
|
111
|
+
|
112
|
+
I18n.locale = :de
|
113
|
+
g.name # => nil
|
114
|
+
|
115
|
+
I18n.fallbacks = true
|
116
|
+
I18n.locale = :de
|
117
|
+
g.name # => 'science fiction'
|
118
|
+
|
119
|
+
</code></pre>
|
120
|
+
|
121
|
+
|
122
|
+
h2. Want some Candy?
|
123
|
+
|
124
|
+
It's nice to have the values of attributes be set or read with the current locale, but Embedded_Localization offers you a couple of additional features..
|
125
|
+
|
126
|
+
h3. Class Methods
|
127
|
+
|
128
|
+
Each class which uses Embedded_Localization will have these additional methods defined:
|
129
|
+
<ul>
|
130
|
+
<li>Klass.translated_attributes
|
131
|
+
<li>Klass.translated?
|
132
|
+
<li>Klass.fallback?
|
133
|
+
</ul>
|
134
|
+
|
135
|
+
e.g.:
|
136
|
+
|
137
|
+
<pre><code>
|
138
|
+
Genre.translated_attributes # => [:name,:description]
|
139
|
+
Genre.translated? # => true
|
140
|
+
Genre.fallback? # => false
|
141
|
+
|
142
|
+
</code></pre>
|
143
|
+
|
144
|
+
h3. Instance Methods
|
145
|
+
|
146
|
+
Each model instance of a class which uses Embedded_Localization will have these additional features:
|
147
|
+
<ul>
|
148
|
+
<li>on-the-fly translations, via <code>.name(:locale)</code>
|
149
|
+
<li>list of translated locales
|
150
|
+
<li>list of translated attributes
|
151
|
+
<li>hash of translation coverage for a given record's attributes or a particular attribute
|
152
|
+
<li>hash of missing translations for a given record's attributes or a particular attribute
|
153
|
+
<li>directly setting and getting attribute values for a given locale; without having to change <code>I18n.locale</code>
|
154
|
+
</ul>
|
155
|
+
|
156
|
+
e.g.:
|
157
|
+
|
158
|
+
<pre><code>
|
159
|
+
I18n.locale = :jp
|
160
|
+
g = Genre.first
|
161
|
+
g.name # => "サイエンスフィクション"
|
162
|
+
|
163
|
+
g.name(:en) # => 'science fiction'
|
164
|
+
g.name(:ko) # => "공상 과학 소설"
|
165
|
+
g.name(:de) # => nil
|
166
|
+
|
167
|
+
g.translated_locales # => [:en,:jp,:ko]
|
168
|
+
g.translated_attributes # => [:name,:description]
|
169
|
+
g.translated? # => true
|
170
|
+
|
171
|
+
g.translation_coverage
|
172
|
+
# => {"name"=>["en", "ko", "jp"] , "description"=>["en", "de", "fr", "ko", "jp", "es"]}
|
173
|
+
|
174
|
+
g.translation_coverage(:name)
|
175
|
+
# => {"name"=>["en", "ko", "jp"]}
|
176
|
+
|
177
|
+
g.translation_missing
|
178
|
+
# => {"name"=>["de", "fr", "es"]}
|
179
|
+
|
180
|
+
g.translation_missing(:display)
|
181
|
+
# => {} # this indicates that there are no missing translations for the :display attribute
|
182
|
+
|
183
|
+
g.get_localized_attribute(:name, :de)
|
184
|
+
# => nil
|
185
|
+
|
186
|
+
g.set_localized_attribute(:name, :de, "Science-Fiction")
|
187
|
+
# => "Science-Fiction"
|
188
|
+
|
189
|
+
</code></pre>
|
190
|
+
|
191
|
+
|
192
|
+
h2. Changes
|
193
|
+
|
194
|
+
This is the initial version.
|
195
|
+
|
196
|
+
h2. Alternative Solutions
|
197
|
+
|
198
|
+
* "Mongoid":https://github.com/mongoid/mongoid - awesome Ruby ORM for MongoDB, which includes in-table localization of attributes (mongoid >= 2.3.0)
|
199
|
+
* "Globalize3":https://github.com/svenfuchs/globalize3 - is an awesome gem, but different approach with more tables in the schema.
|
200
|
+
* "Veger's fork":http://github.com/veger/globalize2 - uses default AR schema for the default locale, delegates to the translations table for other locales only
|
201
|
+
* "TranslatableColumns":http://github.com/iain/translatable_columns - have multiple languages of the same attribute in a model (Iain Hecker)
|
202
|
+
* "localized_record":http://github.com/glennpow/localized_record - allows records to have localized attributes without any modifications to the database (Glenn Powell)
|
203
|
+
* "model_translations":http://github.com/janne/model_translations - Minimal implementation of Globalize2 style model translations (Jan Andersson)
|
204
|
+
|
205
|
+
h2. Related solutions
|
206
|
+
|
207
|
+
* "globalize2_versioning":http://github.com/joshmh/globalize2_versioning - acts_as_versioned style versioning for globalize2 (Joshua Harvey)
|
208
|
+
* "i18n_multi_locales_validations":http://github.com/ZenCocoon/i18n_multi_locales_validations - multi-locales attributes validations to validates attributes from globalize2 translations models (Sébastien Grosjean)
|
209
|
+
* "globalize2 Demo App":http://github.com/svenfuchs/globalize2-demo - demo application for globalize2 (Sven Fuchs)</li>
|
210
|
+
* "migrate_from_globalize1":http://gist.github.com/120867 - migrate model translations from Globalize1 to globalize2 (Tomasz Stachewicz)</li>
|
211
|
+
* "easy_globalize2_accessors":http://github.com/astropanic/easy_globalize2_accessors - easily access (read and write) globalize2-translated fields (astropanic, Tomasz Stachewicz)</li>
|
212
|
+
* "globalize2-easy-translate":http://github.com/bsamman/globalize2-easy-translate - adds methods to easily access or set translated attributes to your model (bsamman)</li>
|
213
|
+
* "batch_translations":http://github.com/alvarezrilla/batch_translations - allow saving multiple globalize2 translations in the same request (Jose Alvarez Rilla)</li>
|
214
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "embedded_localization/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "embedded_localization"
|
7
|
+
s.version = EmbeddedLocalization::VERSION
|
8
|
+
s.authors = ["Tilo Sloboda"]
|
9
|
+
s.email = ["tilo.sloboda@gmail.com"]
|
10
|
+
s.homepage = "http://www.unixgods.org/~tilo/Ruby/embedded_localization"
|
11
|
+
s.summary = %q{Rails I18n: library for embedded ActiveRecord 3 model/data translation}
|
12
|
+
s.description = %q{Rails I18n: Embedded_Localization for ActiveRecord 3 is very lightweight, and allows you to \
|
13
|
+
transparently store translations of attributes right inside each record -- no extra database tables needed to store \
|
14
|
+
the localization data!}
|
15
|
+
|
16
|
+
# s.rubyforge_project = "embedded_localization"
|
17
|
+
s.rubyforge_project = "[none]"
|
18
|
+
|
19
|
+
# s.platform = Gem::Platform::RUBY
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
|
26
|
+
# specify any dependencies here; for example:
|
27
|
+
# s.add_development_dependency "rspec"
|
28
|
+
# s.add_runtime_dependency "rest-client"
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "embedded_localization/version"
|
2
|
+
require 'extensions/hash'
|
3
|
+
|
4
|
+
module EmbeddedLocalization
|
5
|
+
autoload :ActiveRecord, 'embedded_localization/active_record'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
class_attribute :fallback
|
9
|
+
|
10
|
+
def fallback?
|
11
|
+
fallback == true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# we're assuming for now only to be used with ActiveRecord 3, which is auto-required above
|
17
|
+
ActiveRecord::Base.extend(EmbeddedLocalization::ActiveRecord::ActMacro)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module EmbeddedLocalization
|
2
|
+
module ActiveRecord
|
3
|
+
autoload :ActMacro , 'embedded_localization/active_record/act_macro'
|
4
|
+
autoload :ClassMethods , 'embedded_localization/active_record/class_methods'
|
5
|
+
autoload :InstanceMethods , 'embedded_localization/active_record/instance_methods'
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module EmbeddedLocalization
|
2
|
+
module ActiveRecord
|
3
|
+
module ActMacro
|
4
|
+
def translates(*attr_names)
|
5
|
+
return if translates? # cludge to make sure we don't set this up twice..
|
6
|
+
|
7
|
+
options = attr_names.extract_options!
|
8
|
+
# options[:fallback] => true or false
|
9
|
+
|
10
|
+
class_attribute :translated_attribute_names, :translation_options
|
11
|
+
self.translated_attribute_names = attr_names.map(&:to_sym).sort.uniq
|
12
|
+
self.translation_options = options
|
13
|
+
|
14
|
+
include InstanceMethods
|
15
|
+
extend ClassMethods
|
16
|
+
|
17
|
+
# if ActiveRecord::Base is in the parent-chain of the class where we are included into:
|
18
|
+
serialize :i18n # we should also protect it from direct assignment by the user
|
19
|
+
|
20
|
+
# if Mongoid::Document is in the list of classes which extends the class we are included into:
|
21
|
+
# field :i18n, type: Hash
|
22
|
+
# but on the other hand, Mongoid now supports "localized fields" -- so we don't need to re-implement this.
|
23
|
+
# Yay! Durran Jordan is awesome! :-) See: http://mongoid.org/docs/documents/localized.html
|
24
|
+
#
|
25
|
+
# NOTE: I like how Durran implemented the localization in Mongoid.. too bad I didn't see that before.
|
26
|
+
# I'm thinking of re-writing this gem to store the localization hash per attribute... hmm... hmm... thinking...
|
27
|
+
# there would be a couple of advantages to store the I18n-hash per attribute:
|
28
|
+
# - drop-in internationalization for existing String type attributes
|
29
|
+
# - works well with rails scaffolding and with protection of attributes (attr_protected / attr_accessible)
|
30
|
+
# - we can easily hide the internal hash by re-defining the attr-accessors for doing the I18n
|
31
|
+
# - we can better add the per-attribute versioning, which is planned
|
32
|
+
# -
|
33
|
+
|
34
|
+
after_initialize :initialize_i18n_hashes
|
35
|
+
|
36
|
+
|
37
|
+
# dynamically define the accessors for the translated attributes:
|
38
|
+
|
39
|
+
translated_attribute_names.each do |attr_name|
|
40
|
+
class_eval do
|
41
|
+
# define the getter method
|
42
|
+
define_method(attr_name) do |locale = I18n.locale|
|
43
|
+
if ! self.i18n.has_key?(locale)
|
44
|
+
return self.i18n[ I18n.default_locale ][attr_name] if ActsAsI18n.fallback?
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
self.i18n[ locale ][attr_name]
|
48
|
+
end
|
49
|
+
|
50
|
+
# define the setter method
|
51
|
+
define_method(attr_name.to_s+ '=') do |new_translation|
|
52
|
+
self.i18n[I18n.locale] ||= HashWithIndifferentAccess.new
|
53
|
+
self.i18n[I18n.locale][attr_name] = new_translation
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def translates?
|
60
|
+
included_modules.include?(InstanceMethods)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EmbeddedLocalization
|
2
|
+
module ActiveRecord
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
# Returns Array of Symbols for all attributes of this class,
|
6
|
+
# which have translations through acts_as_i18n.
|
7
|
+
# returns an Array of Symbols
|
8
|
+
def translated_attributes
|
9
|
+
translated_attribute_names
|
10
|
+
end
|
11
|
+
|
12
|
+
# Checks whether field with given name is translated field.
|
13
|
+
# Param String or Symbol
|
14
|
+
# Returns true or false
|
15
|
+
def translated?(name)
|
16
|
+
translated_attribute_names.include?(name.to_sym)
|
17
|
+
end
|
18
|
+
|
19
|
+
def fallback?
|
20
|
+
translation_options[:fallback]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module EmbeddedLocalization
|
2
|
+
module ActiveRecord
|
3
|
+
module InstanceMethods
|
4
|
+
|
5
|
+
# maybe a better way to do this is to use a special class LocalizedAttribute < HashWithIndifferentAccess
|
6
|
+
# and use the [] , []= operators... hmm... thinking...
|
7
|
+
|
8
|
+
def get_localized_attribute(attr_name, locale)
|
9
|
+
if ! self.i18n.has_key?(locale)
|
10
|
+
return self.i18n[ I18n.default_locale ][attr_name] if ActsAsI18n.fallback?
|
11
|
+
return nil
|
12
|
+
else
|
13
|
+
self.i18n[locale][attr_name]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_localized_attribute(attr_name, locale, new_translation)
|
18
|
+
self.i18n[locale] ||= HashWithIndifferentAccess.new
|
19
|
+
self.i18n[locale][attr_name] = new_translation
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns all locales used for translation of all documents of this class.
|
23
|
+
# returns an Array of Symbols
|
24
|
+
#
|
25
|
+
def translated_locales
|
26
|
+
self.i18n.keys
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns Array of Symbols for all attributes of this class,
|
30
|
+
# which have translations through acts_as_i18n.
|
31
|
+
# returns an Array of Symbols
|
32
|
+
#
|
33
|
+
def translated_attributes
|
34
|
+
self.class.translated_attributes
|
35
|
+
end
|
36
|
+
|
37
|
+
# Checks whether field with given name is translated field.
|
38
|
+
# Param String or Symbol
|
39
|
+
# Returns true or false
|
40
|
+
#
|
41
|
+
def translated?(name)
|
42
|
+
self.class.translated?(name)
|
43
|
+
# self.class.instance_variable_get(translated_attribute_names).include?(name.to_sym)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Purpose: to see the translation coverage
|
47
|
+
# Returns a Hash of all translated attributes, each with a Hash of the locales it has translations for
|
48
|
+
#
|
49
|
+
def translation_coverage( attribute = nil )
|
50
|
+
attrs = {}
|
51
|
+
self.i18n.each do |lang,hash|
|
52
|
+
hash.keys.each do |attr|
|
53
|
+
attrs[attr.to_sym] ||= []
|
54
|
+
attrs[attr.to_sym] << lang
|
55
|
+
end
|
56
|
+
end
|
57
|
+
if attribute.nil?
|
58
|
+
return attrs
|
59
|
+
else
|
60
|
+
return attrs[attribute.to_sym]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Purpose: to quickly see if attribute translations are missing
|
65
|
+
# Returns a Hash of attributes, each with a Hash of the locales that are missing translations
|
66
|
+
# If an attribute has complete translation coverage, it will not be listed
|
67
|
+
# If the result is an empty Hash, then no attributes are missing translations
|
68
|
+
#
|
69
|
+
# Needs all the desired locales to be present in 'translated_locales'
|
70
|
+
# e.g. each locale must be present in at least one of the translated attributes
|
71
|
+
#
|
72
|
+
def translation_missing( attribute = nil )
|
73
|
+
missing = {}
|
74
|
+
current_locales_used = translated_locales # ... across all attributes
|
75
|
+
|
76
|
+
translated_attributes.each do |attr|
|
77
|
+
missing_locales = current_locales_used - translation_coverage(attr.to_sym)
|
78
|
+
if missing_locales.size > 0
|
79
|
+
missing[attr.to_sym] = missing_locales
|
80
|
+
end
|
81
|
+
end
|
82
|
+
if attribute.nil?
|
83
|
+
return missing
|
84
|
+
else
|
85
|
+
return missing[attribute.to_sym]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
# initialized the serialized 'i18n' attribute with Hash of Hashes,
|
91
|
+
# containing all pre-defined translated attributes with nil value
|
92
|
+
def initialize_i18n_hashes
|
93
|
+
self.i18n ||= HashWithIndifferentAccess.new
|
94
|
+
self.i18n[ I18n.locale ] ||= HashWithIndifferentAccess.new(Hash.zip(translated_attribute_names,[]))
|
95
|
+
if I18n.locale != I18n.default_locale
|
96
|
+
self.i18n[ I18n.default_locale ] ||= HashWithIndifferentAccess.new(Hash.zip(translated_attribute_names,[]))
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: embedded_localization
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.3
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tilo Sloboda
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-01-27 00:00:00 Z
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: |-
|
17
|
+
Rails I18n: Embedded_Localization for ActiveRecord 3 is very lightweight, and allows you to \
|
18
|
+
transparently store translations of attributes right inside each record -- no extra database tables needed to store \
|
19
|
+
the localization data!
|
20
|
+
email:
|
21
|
+
- tilo.sloboda@gmail.com
|
22
|
+
executables: []
|
23
|
+
|
24
|
+
extensions: []
|
25
|
+
|
26
|
+
extra_rdoc_files: []
|
27
|
+
|
28
|
+
files:
|
29
|
+
- .gitignore
|
30
|
+
- Gemfile
|
31
|
+
- README.textile
|
32
|
+
- Rakefile
|
33
|
+
- embedded_localization.gemspec
|
34
|
+
- lib/embedded_localization.rb
|
35
|
+
- lib/embedded_localization/active_record.rb
|
36
|
+
- lib/embedded_localization/active_record/act_macro.rb
|
37
|
+
- lib/embedded_localization/active_record/class_methods.rb
|
38
|
+
- lib/embedded_localization/active_record/instance_methods.rb
|
39
|
+
- lib/embedded_localization/version.rb
|
40
|
+
- lib/extensions/hash.rb
|
41
|
+
homepage: http://www.unixgods.org/~tilo/Ruby/embedded_localization
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project: "[none]"
|
64
|
+
rubygems_version: 1.8.13
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: "Rails I18n: library for embedded ActiveRecord 3 model/data translation"
|
68
|
+
test_files: []
|
69
|
+
|