lolita-translation 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -2
- data/VERSION +1 -1
- data/app/assets/.gitkeep +0 -0
- data/app/assets/javascripts/.gitkeep +0 -0
- data/{public → app/assets}/javascripts/lolita/translation.js +0 -0
- data/{public → app/assets}/stylesheets/lolita/translation.css +0 -0
- data/lib/lolita-translation.rb +6 -1
- data/lib/lolita-translation/has_translations.rb +291 -215
- data/lolita-translation.gemspec +21 -21
- metadata +23 -23
- data/lib/generators/lolita_translation/assets_generator.rb +0 -13
- data/lib/generators/lolita_translation/install_generator.rb +0 -13
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/app/assets/.gitkeep
ADDED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/lolita-translation.rb
CHANGED
@@ -5,6 +5,11 @@ require 'lolita-translation/rails'
|
|
5
5
|
|
6
6
|
module Lolita
|
7
7
|
module Translation
|
8
|
+
|
9
|
+
def self.included(base_class)
|
10
|
+
base_class.extend(Lolita::Translation::SingletonMethods)
|
11
|
+
end
|
12
|
+
|
8
13
|
class << self
|
9
14
|
def translatable?(tab)
|
10
15
|
fields = tab.fields.reject{|field|
|
@@ -23,7 +28,7 @@ module Lolita
|
|
23
28
|
fields = tab.fields.reject{|field|
|
24
29
|
!resource.class.translation_attrs.include?(field.name.to_sym)
|
25
30
|
}
|
26
|
-
fields << Lolita::Configuration::Field.add(nested_form.dbi,:locale,:hidden)
|
31
|
+
fields << Lolita::Configuration::Factory::Field.add(nested_form.dbi,:locale,:hidden)
|
27
32
|
nested_form.fields=fields
|
28
33
|
nested_form
|
29
34
|
end
|
@@ -1,111 +1,186 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
3
|
+
module Lolita
|
4
|
+
module Translation
|
5
|
+
module SingletonMethods
|
6
|
+
# Provides ability to add the translations for the model using delegate pattern.
|
7
|
+
# Uses has_many association to the ModelNameTranslation.
|
8
|
+
#
|
9
|
+
# For example you have model Article with attributes title and text.
|
10
|
+
# You want that attributes title and text to be translated.
|
11
|
+
# For this reason you need to generate new model ArticleTranslation.
|
12
|
+
# In migration you need to add:
|
13
|
+
#
|
14
|
+
# create_table :article_translations do |t|
|
15
|
+
# t.references :article, :null => false
|
16
|
+
# t.string :locale, :length => 2, :null => false
|
17
|
+
# t.string :name, :null => false
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# add_index :articles, [:article_id, :locale], :unique => true, :name => 'unique_locale_for_article_id'
|
21
|
+
#
|
22
|
+
# And in the Article model:
|
23
|
+
#
|
24
|
+
# translations :title, :text
|
25
|
+
#
|
26
|
+
# This will adds:
|
27
|
+
#
|
28
|
+
# * named_scope (translated) and has_many association to the Article model
|
29
|
+
# * locale presence validation to the ArticleTranslation model.
|
30
|
+
#
|
31
|
+
# Notice: if you want to have validates_presence_of :article, you should use :inverse_of.
|
32
|
+
# Support this by yourself. Better is always to use artile.translations.build() method.
|
33
|
+
#
|
34
|
+
# For more information please read API. Feel free to write me an email to:
|
35
|
+
# dmitry.polushkin@gmail.com.
|
36
|
+
#
|
37
|
+
# ===
|
38
|
+
#
|
39
|
+
# You also can pass attributes and options to the translations class method:
|
40
|
+
#
|
41
|
+
# translations :title, :text, :fallback => true, :writer => true, :nil => nil
|
42
|
+
#
|
43
|
+
# ===
|
44
|
+
#
|
45
|
+
# Configuration options:
|
46
|
+
#
|
47
|
+
# * <tt>:fallback</tt> - if translation for the current locale not found.
|
48
|
+
# By default true.
|
49
|
+
# Uses algorithm of fallback:
|
50
|
+
# 0) current translation (using I18n.locale);
|
51
|
+
# 1) default locale (using I18n.default_locale);
|
52
|
+
# 2) :nil value (see <tt>:nil</tt> configuration option)
|
53
|
+
# * <tt>:reader</tt> - add reader attributes to the model and delegate them
|
54
|
+
# to the translation model columns. Add's fallback if it is set to true.
|
55
|
+
# * <tt>:writer</tt> - add writer attributes to the model and assign them
|
56
|
+
# to the translation model attributes.
|
57
|
+
# * <tt>:nil</tt> - when reader cant find string, it returns by default an
|
58
|
+
# empty string. If you want to change this setting for example to nil,
|
59
|
+
# add :nil => nil
|
60
|
+
#
|
61
|
+
# ===
|
62
|
+
#
|
63
|
+
# When you are using <tt>:writer</tt> option, you can create translations using
|
64
|
+
# update_attributes method. For example:
|
65
|
+
#
|
66
|
+
# Article.create!
|
67
|
+
# Article.update_attributes(:title => 'title', :text => 'text')
|
68
|
+
#
|
69
|
+
# ===
|
70
|
+
#
|
71
|
+
# <tt>translated</tt> named_scope is useful when you want to find only those
|
72
|
+
# records that are translated to a specific locale.
|
73
|
+
# For example if you want to find all Articles that is translated to an english
|
74
|
+
# language, you can write: Article.translated(:en)
|
75
|
+
#
|
76
|
+
# <tt>has_translation?(locale)</tt> method, that returns true if object's model
|
77
|
+
# have a translation for a specified locale
|
78
|
+
#
|
79
|
+
# <tt>translation(locale)</tt> method finds translation with specified locale.
|
80
|
+
#
|
81
|
+
# <tt>all_translations</tt> method that returns all possible translations in
|
82
|
+
# ordered hash (useful when creating forms with nested attributes).
|
83
|
+
def translations *attrs
|
84
|
+
include Lolita::Translation::InstanceMethods
|
85
|
+
options = {
|
86
|
+
:fallback => true,
|
87
|
+
:reader => true,
|
88
|
+
:writer => false,
|
89
|
+
:nil => ''
|
90
|
+
}.merge(attrs.extract_options!)
|
91
|
+
options.assert_valid_keys([:fallback, :reader, :writer, :nil])
|
92
|
+
self.extend(Lolita::Translation::ClassMethods)
|
93
|
+
self.class_eval do
|
94
|
+
translation_class_name = "#{self.name}Translation"
|
95
|
+
translation_class = self.define_translation_class(translation_class_name, attrs)
|
96
|
+
belongs_to = self.name.demodulize.underscore.to_sym
|
97
|
+
|
98
|
+
write_inheritable_attribute :has_translations_options, options
|
99
|
+
class_inheritable_reader :has_translations_options
|
100
|
+
|
101
|
+
write_inheritable_attribute :columns_has_translations, (columns rescue []).collect{|col| col if attrs.include?(col.name.to_sym)}.compact
|
102
|
+
class_inheritable_reader :columns_has_translations
|
103
|
+
|
104
|
+
if options[:reader]
|
105
|
+
attrs.each do |name|
|
106
|
+
send :define_method, name do
|
107
|
+
unless I18n.default_locale == I18n.locale
|
108
|
+
translation = self.translation(I18n.locale)
|
109
|
+
if translation.nil?
|
110
|
+
if has_translations_options[:fallback]
|
111
|
+
(self[name].nil? || self[name].blank?) ? has_translations_options[:nil] : self[name].set_origins(self,name)
|
112
|
+
else
|
113
|
+
has_translations_options[:nil]
|
114
|
+
end
|
115
|
+
else
|
116
|
+
if @return_raw_data
|
117
|
+
(self[name].nil? || self[name].blank?) ? has_translations_options[:nil] : self[name].set_origins(self,name)
|
118
|
+
else
|
119
|
+
value = translation.send(name) and value.set_origins(self,name)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
else
|
123
|
+
(self[name].nil? || self[name].blank?) ? has_translations_options[:nil] : self[name].set_origins(self,name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
@translation_attrs = attrs
|
130
|
+
def self.translation_attrs
|
131
|
+
@translation_attrs
|
132
|
+
end
|
133
|
+
#adapter = Lolita::DBI::Base.create(self)
|
134
|
+
has_many :translations, :class_name => translation_class_name, :foreign_key => translation_class.master_id, :dependent => :destroy
|
135
|
+
accepts_nested_attributes_for :translations, :allow_destroy => true, :reject_if => proc { |attributes| columns_has_translations.collect{|col| attributes[col.name].blank? ? nil : 1}.compact.empty? }
|
136
|
+
translation_class.belongs_to belongs_to
|
137
|
+
translation_class.validates_presence_of :locale
|
138
|
+
translation_class.validates_uniqueness_of :locale, :scope => translation_class.master_id
|
139
|
+
|
140
|
+
# Workaround to support Rails 2
|
141
|
+
scope_method =:scope
|
142
|
+
|
143
|
+
send scope_method, :translated, lambda { |locale|
|
144
|
+
where("#{translation_class.table_name}.locale = ?", locale.to_s).joins(:translations)
|
145
|
+
}
|
146
|
+
|
147
|
+
class << self
|
148
|
+
|
149
|
+
def find_with_translations(*args,&block)
|
150
|
+
unless I18n.locale == I18n.default_locale
|
151
|
+
if args && args[0].kind_of?(Hash)
|
152
|
+
args[0][:include] ||=[]
|
153
|
+
args[0][:include] << :translations
|
154
|
+
end
|
155
|
+
end
|
156
|
+
find_without_translations *args, &block
|
157
|
+
end
|
158
|
+
alias_method_chain :find, :translations
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
module ClassMethods
|
91
166
|
# adds :translations to :includes if current locale differs from default
|
92
167
|
#FIXME is this enough with find or need to create chain for find_last, find_first and others?
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
168
|
+
# def find(*args)
|
169
|
+
# if args[0].kind_of?(Hash)
|
170
|
+
# args[0][:include] ||= []
|
171
|
+
# args[0][:include] << :translations
|
172
|
+
# end unless I18n.locale == I18n.default_locale
|
173
|
+
# find_without_translations(*args)
|
174
|
+
# end
|
175
|
+
|
101
176
|
# Defines given class recursively
|
102
177
|
# Example:
|
103
178
|
# create_class('Cms::Text::Page', Object, ActiveRecord::Base)
|
104
179
|
# => Cms::Text::Page
|
105
|
-
def create_class(class_name, parent, superclass, &block)
|
180
|
+
def create_class(class_name, parent, superclass=nil, &block)
|
106
181
|
first,*other = class_name.split("::")
|
107
182
|
if other.empty?
|
108
|
-
klass = Class.new
|
183
|
+
klass = superclass ? Class.new(superclass, &block) : Class.new(&block)
|
109
184
|
parent.const_set(first, klass)
|
110
185
|
else
|
111
186
|
klass = Class.new
|
@@ -117,27 +192,39 @@ class ActiveRecord::Base
|
|
117
192
|
create_class(other.join('::'), parent, superclass, &block)
|
118
193
|
end
|
119
194
|
end
|
195
|
+
|
120
196
|
# defines "ModelNameTranslation" if it's not defined manualy
|
121
197
|
def define_translation_class name, attrs
|
122
198
|
klass = name.constantize rescue nil
|
199
|
+
adapter = Lolita::DBI::Base.create(self)
|
200
|
+
|
123
201
|
unless klass
|
124
|
-
klass = create_class(name, Object,
|
202
|
+
klass = create_class(name, Object, get_orm_class(adapter)) do
|
203
|
+
if adapter.dbi.adapter_name == :mongoid
|
204
|
+
include Mongoid::Document
|
205
|
+
end
|
125
206
|
# set's real table name
|
126
|
-
|
207
|
+
translation_adapter = Lolita::DBI::Base.create(self)
|
208
|
+
translation_adapter.collection_name = adapter.collection_name.to_s.singularize + "_translation"
|
209
|
+
|
127
210
|
cattr_accessor :translate_attrs, :master_id
|
211
|
+
|
128
212
|
# override validate to vaidate only translate fields from master Class
|
129
213
|
def validate
|
130
214
|
item = self.class.name.sub('Translation','').constantize.new(self.attributes.clone.delete_if{|k,_| !self.class.translate_attrs.include?(k.to_sym)})
|
131
|
-
|
132
|
-
|
215
|
+
item_adapter = Lolita::DBI::Adapter.add(item.class)
|
216
|
+
self_adapter = Lolita::DBI::Adapter.add(self)
|
217
|
+
was_table_name = item_adapter.collection_name
|
218
|
+
item_adapter.collection_name = self_adapter.collection_name
|
133
219
|
item.valid? rescue
|
134
220
|
self.class.translate_attrs.each do |attr|
|
135
221
|
errors_on_attr = item.errors.on(attr)
|
136
222
|
self.errors.add(attr,errors_on_attr) if errors_on_attr
|
137
223
|
end
|
138
|
-
|
224
|
+
item_adapter.collection_name = was_table_name
|
139
225
|
end
|
140
|
-
extend TranslationClassMethods
|
226
|
+
extend Lolita::TranslationClassMethods
|
227
|
+
|
141
228
|
end
|
142
229
|
klass.translate_attrs = attrs
|
143
230
|
else
|
@@ -151,6 +238,10 @@ class ActiveRecord::Base
|
|
151
238
|
klass.extract_master_id(name)
|
152
239
|
klass
|
153
240
|
end
|
241
|
+
|
242
|
+
def get_orm_class(adapter)
|
243
|
+
adapter.dbi.adapter_name == :active_record ? ActiveRecord::Base : nil
|
244
|
+
end
|
154
245
|
# creates translation table and adds missing fields
|
155
246
|
# So at first add the "translations :name, :desc" in your model
|
156
247
|
# then put YourModel.sync_translation_table! in db/seed.rb and run "rake db:seed"
|
@@ -159,141 +250,126 @@ class ActiveRecord::Base
|
|
159
250
|
def sync_translation_table!
|
160
251
|
out = StringIO.new
|
161
252
|
$stdout = out
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
253
|
+
self_adapter = Lolita::DBI::Base.create(self)
|
254
|
+
translations_class = self.reflect_on_association(:translations).klass
|
255
|
+
translations_adapter = Lolita::DBI::Base.create(translations_class)
|
256
|
+
|
257
|
+
if translations_adapter.dbi.adapter_name == :active_record
|
258
|
+
translations_table = translations_adapter.collection_name
|
259
|
+
|
260
|
+
unless ActiveRecord::Migration::table_exists?(translations_table)
|
261
|
+
ActiveRecord::Migration.create_table translations_table do |t|
|
262
|
+
t.integer translations_class.master_id, :null => false
|
263
|
+
t.string :locale, :null => false, :limit => 5
|
264
|
+
columns_has_translations.each do |col|
|
265
|
+
t.send(col.type,col.name)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
ActiveRecord::Migration.add_index translations_table, [translations_class.master_id, :locale], :unique => true
|
269
|
+
translations_class.reset_column_information
|
270
|
+
else
|
271
|
+
changes = false
|
168
272
|
columns_has_translations.each do |col|
|
169
|
-
|
273
|
+
unless translations_class.columns_hash.has_key?(col.name)
|
274
|
+
ActiveRecord::Migration.add_column(translations_table, col.name, col.type)
|
275
|
+
changes = true
|
276
|
+
end
|
170
277
|
end
|
278
|
+
translations_class.reset_column_information if changes
|
171
279
|
end
|
172
|
-
|
173
|
-
translations_class.
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
280
|
+
elsif translations_adapter.dbi.adapter_name == :mongoid
|
281
|
+
unless translations_class.fields["locale"]
|
282
|
+
translations_class.class_eval do
|
283
|
+
field(self.master_id, :type => Integer)
|
284
|
+
field :locale, :type => String
|
285
|
+
columns_has_translations.each do |col|
|
286
|
+
field col.name, :type => col.type
|
287
|
+
end
|
288
|
+
index(
|
289
|
+
[
|
290
|
+
[ self.master_id, Mongo::ASCENDING ],
|
291
|
+
[ :locale, Mongo::ASCENDING ]
|
292
|
+
],
|
293
|
+
unique: true
|
294
|
+
)
|
295
|
+
end
|
296
|
+
else
|
297
|
+
columns_has_translations.each do |col|
|
298
|
+
unless translations_class.fields[col.name.to_s]
|
299
|
+
translations_class.field(col.name,:type => col.type)
|
300
|
+
end
|
180
301
|
end
|
181
302
|
end
|
182
|
-
translations_class.reset_column_information if changes
|
183
303
|
end
|
184
304
|
$stdout = STDOUT
|
185
305
|
end
|
186
306
|
end
|
187
307
|
|
188
|
-
|
189
|
-
translation_class = self.define_translation_class(translation_class_name, attrs)
|
190
|
-
belongs_to = self.name.demodulize.underscore.to_sym
|
191
|
-
|
192
|
-
write_inheritable_attribute :has_translations_options, options
|
193
|
-
class_inheritable_reader :has_translations_options
|
194
|
-
|
195
|
-
write_inheritable_attribute :columns_has_translations, (columns rescue []).collect{|col| col if attrs.include?(col.name.to_sym)}.compact
|
196
|
-
class_inheritable_reader :columns_has_translations
|
308
|
+
module InstanceMethods
|
197
309
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
def translation(locale)
|
216
|
-
find_translation(locale.to_s)
|
217
|
-
end
|
218
|
-
|
219
|
-
def all_translations
|
220
|
-
t = I18n.available_locales.map do |locale|
|
221
|
-
[locale, find_or_build_translation(locale)]
|
310
|
+
# forces given locale
|
311
|
+
# I18n.locale = :lv
|
312
|
+
# a = Article.find 18
|
313
|
+
# a.title
|
314
|
+
# => "LV title"
|
315
|
+
# a.in(:en).title
|
316
|
+
# => "EN title"
|
317
|
+
def in locale
|
318
|
+
locale.to_sym == I18n.default_locale ? self : find_translation(locale)
|
319
|
+
end
|
320
|
+
|
321
|
+
def find_or_build_translation(*args)
|
322
|
+
locale = args.first.to_s
|
323
|
+
build = args.second.present?
|
324
|
+
find_translation(locale) || (build ? self.translations.build(:locale => locale) : self.translations.new(:locale => locale))
|
222
325
|
end
|
223
|
-
ActiveSupport::OrderedHash[t]
|
224
|
-
end
|
225
326
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
327
|
+
def translation(locale)
|
328
|
+
find_translation(locale.to_s)
|
329
|
+
end
|
230
330
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
I18n.available_locales.clone.delete_if{|l| l == I18n.default_locale}.each do |l|
|
235
|
-
options = {:locale => l.to_s}
|
236
|
-
options[self.class.reflections[:translations].class_name.constantize.master_id] = self.id unless self.new_record?
|
237
|
-
self.translations.build(options) unless self.translations.map(&:locale).include?(l.to_s)
|
331
|
+
def all_translations
|
332
|
+
t = I18n.available_locales.map do |locale|
|
333
|
+
[locale, find_or_build_translation(locale)]
|
238
334
|
end
|
335
|
+
ActiveSupport::OrderedHash[t]
|
239
336
|
end
|
240
|
-
end
|
241
337
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
(self[name].nil? || self[name].blank?) ? has_translations_options[:nil] : self[name].set_origins(self,name)
|
256
|
-
else
|
257
|
-
value = translation.send(name) and value.set_origins(self,name)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
else
|
261
|
-
(self[name].nil? || self[name].blank?) ? has_translations_options[:nil] : self[name].set_origins(self,name)
|
338
|
+
def has_translation?(locale)
|
339
|
+
return true if locale == I18n.default_locale
|
340
|
+
find_translation(locale).present?
|
341
|
+
end
|
342
|
+
|
343
|
+
# if object is new, then nested slaves ar built for all available locales
|
344
|
+
def build_nested_translations
|
345
|
+
if (I18n.available_locales.size - 1) > self.translations.size
|
346
|
+
I18n.available_locales.clone.delete_if{|l| l == I18n.default_locale}.each do |l|
|
347
|
+
options = {:locale => l.to_s}
|
348
|
+
self_adapter = Lolita::DBI::Base.create(self.class)
|
349
|
+
options[self_adapter.reflect_on_association(:translations).klass.master_id] = self.id unless self.new_record?
|
350
|
+
self.translations.build(options) unless self.translations.map(&:locale).include?(l.to_s)
|
262
351
|
end
|
263
352
|
end
|
264
353
|
end
|
265
|
-
end
|
266
|
-
|
267
|
-
@translation_attrs = attrs
|
268
|
-
def self.translation_attrs
|
269
|
-
@translation_attrs
|
270
|
-
end
|
271
|
-
has_many :translations, :class_name => translation_class_name, :foreign_key => translation_class.master_id, :dependent => :destroy
|
272
|
-
accepts_nested_attributes_for :translations, :allow_destroy => true, :reject_if => proc { |attributes| columns_has_translations.collect{|col| attributes[col.name].blank? ? nil : 1}.compact.empty? }
|
273
|
-
translation_class.belongs_to belongs_to
|
274
|
-
translation_class.validates_presence_of :locale
|
275
|
-
translation_class.validates_uniqueness_of :locale, :scope => translation_class.master_id
|
276
|
-
|
277
|
-
# Workaround to support Rails 2
|
278
|
-
scope_method = if ActiveRecord::VERSION::MAJOR < 3 then :named_scope else :scope end
|
279
354
|
|
280
|
-
|
355
|
+
|
356
|
+
#private is no good
|
281
357
|
|
282
|
-
|
358
|
+
def find_translation(locale)
|
359
|
+
locale = locale.to_s
|
360
|
+
translations.detect { |t| t.locale == locale }
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
283
364
|
|
284
|
-
|
285
|
-
|
286
|
-
|
365
|
+
module TranslationClassMethods
|
366
|
+
# sets real master_id it's aware of STI
|
367
|
+
def extract_master_id name
|
368
|
+
master_class = name.sub('Translation','').constantize
|
369
|
+
#FIXME why need to check superclass ?
|
370
|
+
class_name = master_class.name #!master_class.superclass.abstract_class? ? master_class.superclass.name : master_class.name
|
371
|
+
self.master_id = :"#{class_name.demodulize.underscore}_id"
|
287
372
|
end
|
288
373
|
end
|
289
374
|
end
|
290
375
|
|
291
|
-
module TranslationClassMethods
|
292
|
-
# sets real master_id it's aware of STI
|
293
|
-
def extract_master_id name
|
294
|
-
master_class = name.sub('Translation','').constantize
|
295
|
-
#FIXME why need to check superclass ?
|
296
|
-
class_name = master_class.name #!master_class.superclass.abstract_class? ? master_class.superclass.name : master_class.name
|
297
|
-
self.master_id = :"#{class_name.demodulize.underscore}_id"
|
298
|
-
end
|
299
|
-
end
|
data/lolita-translation.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.
|
7
|
+
s.name = "lolita-translation"
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
11
|
+
s.authors = ["ITHouse", "Gatis Tomsons", "Arturs Meisters"]
|
12
|
+
s.date = "2011-09-05"
|
13
|
+
s.description = "Translates models in Lolita"
|
14
|
+
s.email = "support@ithouse.lv"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
17
|
"README.md"
|
@@ -23,32 +23,32 @@ Gem::Specification.new do |s|
|
|
23
23
|
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
|
+
"app/assets/.gitkeep",
|
27
|
+
"app/assets/javascripts/.gitkeep",
|
28
|
+
"app/assets/javascripts/lolita/translation.js",
|
29
|
+
"app/assets/stylesheets/lolita/translation.css",
|
26
30
|
"app/views/components/lolita/translation/_assets.html.erb",
|
27
31
|
"app/views/components/lolita/translation/_language_wrap.html.erb",
|
28
32
|
"app/views/components/lolita/translation/_switch.html.erb",
|
29
33
|
"config/locales/en.yml",
|
30
34
|
"config/locales/lv.yml",
|
31
35
|
"lib/generators/lolita_translation/USAGE",
|
32
|
-
"lib/generators/lolita_translation/assets_generator.rb",
|
33
36
|
"lib/generators/lolita_translation/has_translations_generator.rb",
|
34
|
-
"lib/generators/lolita_translation/install_generator.rb",
|
35
37
|
"lib/lolita-translation.rb",
|
36
38
|
"lib/lolita-translation/has_translations.rb",
|
37
39
|
"lib/lolita-translation/rails.rb",
|
38
40
|
"lib/lolita-translation/string.rb",
|
39
41
|
"lib/tasks/has_translations_tasks.rake",
|
40
42
|
"lolita-translation.gemspec",
|
41
|
-
"public/javascripts/lolita/translation.js",
|
42
|
-
"public/stylesheets/lolita/translation.css",
|
43
43
|
"spec/has_translations_spec.rb",
|
44
44
|
"spec/spec.opts",
|
45
45
|
"spec/spec_helper.rb"
|
46
46
|
]
|
47
|
-
s.homepage =
|
48
|
-
s.licenses = [
|
49
|
-
s.require_paths = [
|
50
|
-
s.rubygems_version =
|
51
|
-
s.summary =
|
47
|
+
s.homepage = "http://github.com/ithouse/lolita-translations"
|
48
|
+
s.licenses = ["MIT"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = "1.8.10"
|
51
|
+
s.summary = "Lolita models translation plugin"
|
52
52
|
s.test_files = [
|
53
53
|
"spec/has_translations_spec.rb",
|
54
54
|
"spec/spec_helper.rb"
|
@@ -58,23 +58,23 @@ Gem::Specification.new do |s|
|
|
58
58
|
s.specification_version = 3
|
59
59
|
|
60
60
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
61
|
-
s.add_runtime_dependency(%q<rails>, ["
|
62
|
-
s.add_runtime_dependency(%q<lolita>, ["~> 3.
|
61
|
+
s.add_runtime_dependency(%q<rails>, ["~> 3.1.0"])
|
62
|
+
s.add_runtime_dependency(%q<lolita>, ["~> 3.2.0.rc1"])
|
63
63
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
64
64
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
65
65
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
66
66
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
67
67
|
else
|
68
|
-
s.add_dependency(%q<rails>, ["
|
69
|
-
s.add_dependency(%q<lolita>, ["~> 3.
|
68
|
+
s.add_dependency(%q<rails>, ["~> 3.1.0"])
|
69
|
+
s.add_dependency(%q<lolita>, ["~> 3.2.0.rc1"])
|
70
70
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
71
71
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
72
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
73
73
|
s.add_dependency(%q<rcov>, [">= 0"])
|
74
74
|
end
|
75
75
|
else
|
76
|
-
s.add_dependency(%q<rails>, ["
|
77
|
-
s.add_dependency(%q<lolita>, ["~> 3.
|
76
|
+
s.add_dependency(%q<rails>, ["~> 3.1.0"])
|
77
|
+
s.add_dependency(%q<lolita>, ["~> 3.2.0.rc1"])
|
78
78
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
79
79
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
80
80
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lolita-translation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,33 +11,33 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2011-09-
|
14
|
+
date: 2011-09-05 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
18
|
-
requirement: &
|
18
|
+
requirement: &73080930 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
|
-
- -
|
21
|
+
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 3.
|
23
|
+
version: 3.1.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *73080930
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: lolita
|
29
|
-
requirement: &
|
29
|
+
requirement: &73080430 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 3.
|
34
|
+
version: 3.2.0.rc1
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *73080430
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: shoulda
|
40
|
-
requirement: &
|
40
|
+
requirement: &73079880 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *73079880
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: bundler
|
51
|
-
requirement: &
|
51
|
+
requirement: &73079300 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ~>
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: 1.0.0
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *73079300
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: jeweler
|
62
|
-
requirement: &
|
62
|
+
requirement: &73078900 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ~>
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: 1.5.2
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *73078900
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rcov
|
73
|
-
requirement: &
|
73
|
+
requirement: &73078470 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *73078470
|
82
82
|
description: Translates models in Lolita
|
83
83
|
email: support@ithouse.lv
|
84
84
|
executables: []
|
@@ -93,23 +93,23 @@ files:
|
|
93
93
|
- README.md
|
94
94
|
- Rakefile
|
95
95
|
- VERSION
|
96
|
+
- app/assets/.gitkeep
|
97
|
+
- app/assets/javascripts/.gitkeep
|
98
|
+
- app/assets/javascripts/lolita/translation.js
|
99
|
+
- app/assets/stylesheets/lolita/translation.css
|
96
100
|
- app/views/components/lolita/translation/_assets.html.erb
|
97
101
|
- app/views/components/lolita/translation/_language_wrap.html.erb
|
98
102
|
- app/views/components/lolita/translation/_switch.html.erb
|
99
103
|
- config/locales/en.yml
|
100
104
|
- config/locales/lv.yml
|
101
105
|
- lib/generators/lolita_translation/USAGE
|
102
|
-
- lib/generators/lolita_translation/assets_generator.rb
|
103
106
|
- lib/generators/lolita_translation/has_translations_generator.rb
|
104
|
-
- lib/generators/lolita_translation/install_generator.rb
|
105
107
|
- lib/lolita-translation.rb
|
106
108
|
- lib/lolita-translation/has_translations.rb
|
107
109
|
- lib/lolita-translation/rails.rb
|
108
110
|
- lib/lolita-translation/string.rb
|
109
111
|
- lib/tasks/has_translations_tasks.rake
|
110
112
|
- lolita-translation.gemspec
|
111
|
-
- public/javascripts/lolita/translation.js
|
112
|
-
- public/stylesheets/lolita/translation.css
|
113
113
|
- spec/has_translations_spec.rb
|
114
114
|
- spec/spec.opts
|
115
115
|
- spec/spec_helper.rb
|
@@ -128,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
128
|
version: '0'
|
129
129
|
segments:
|
130
130
|
- 0
|
131
|
-
hash:
|
131
|
+
hash: 735045519
|
132
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
133
|
none: false
|
134
134
|
requirements:
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
139
|
rubyforge_project:
|
140
|
-
rubygems_version: 1.8.
|
140
|
+
rubygems_version: 1.8.10
|
141
141
|
signing_key:
|
142
142
|
specification_version: 3
|
143
143
|
summary: Lolita models translation plugin
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'generators/helpers/file_helper'
|
2
|
-
module LolitaTranslation
|
3
|
-
module Generators
|
4
|
-
class AssetsGenerator < Rails::Generators::Base
|
5
|
-
include Lolita::Generators::FileHelper
|
6
|
-
desc "Copy all from public directory to project public directory."
|
7
|
-
def copy_all
|
8
|
-
root=File.expand_path("../../../../",__FILE__)
|
9
|
-
copy_dir("public",:root=>root)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|