mongoid_globalize 0.1.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/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +74 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +0 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/lib/mongoid_globalize/act_macro.rb +23 -0
- data/lib/mongoid_globalize/adapter.rb +73 -0
- data/lib/mongoid_globalize/attributes.rb +25 -0
- data/lib/mongoid_globalize/class_methods.rb +64 -0
- data/lib/mongoid_globalize/document_translation.rb +30 -0
- data/lib/mongoid_globalize/instance_methods.rb +174 -0
- data/lib/mongoid_globalize.rb +69 -0
- data/mongoid_globalize.gemspec +86 -0
- data/spec/data/models.rb +77 -0
- data/spec/mongoid_globalize/attributes_spec.rb +138 -0
- data/spec/mongoid_globalize/clone_spec.rb +51 -0
- data/spec/mongoid_globalize/dirty_tracking_spec.rb +62 -0
- data/spec/mongoid_globalize/fallbacks_spec.rb +135 -0
- data/spec/mongoid_globalize/locale_spec.rb +89 -0
- data/spec/mongoid_globalize/set_translations_spec.rb +49 -0
- data/spec/mongoid_globalize/translation_class_spec.rb +57 -0
- data/spec/mongoid_globalize/validations_spec.rb +93 -0
- data/spec/mongoid_globalize_spec.rb +173 -0
- data/spec/spec_helper.rb +77 -0
- metadata +170 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@mongoid-globalize --create
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'activemodel', '3.1.0.rc4'
|
4
|
+
gem 'mongoid', :git => 'git://github.com/mongoid/mongoid.git'
|
5
|
+
gem 'bson_ext'
|
6
|
+
|
7
|
+
group :development, :test do
|
8
|
+
gem 'rspec'
|
9
|
+
gem 'mongoid-rspec'
|
10
|
+
gem 'database_cleaner'
|
11
|
+
gem 'ruby-debug19'
|
12
|
+
gem 'jeweler'
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/mongoid/mongoid.git
|
3
|
+
revision: e2540c818ebb1d37b3a8d1b7e6dd6836ce16d445
|
4
|
+
specs:
|
5
|
+
mongoid (2.1.0)
|
6
|
+
activemodel (~> 3.0)
|
7
|
+
mongo (~> 1.3)
|
8
|
+
tzinfo (~> 0.3.22)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activemodel (3.1.0.rc4)
|
14
|
+
activesupport (= 3.1.0.rc4)
|
15
|
+
bcrypt-ruby (~> 2.1.4)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
i18n (~> 0.6)
|
18
|
+
activesupport (3.1.0.rc4)
|
19
|
+
multi_json (~> 1.0)
|
20
|
+
archive-tar-minitar (0.5.2)
|
21
|
+
bcrypt-ruby (2.1.4)
|
22
|
+
bson (1.3.1)
|
23
|
+
bson_ext (1.3.1)
|
24
|
+
builder (3.0.0)
|
25
|
+
columnize (0.3.4)
|
26
|
+
database_cleaner (0.6.7)
|
27
|
+
diff-lcs (1.1.2)
|
28
|
+
git (1.2.5)
|
29
|
+
i18n (0.6.0)
|
30
|
+
jeweler (1.6.4)
|
31
|
+
bundler (~> 1.0)
|
32
|
+
git (>= 1.2.5)
|
33
|
+
rake
|
34
|
+
linecache19 (0.5.12)
|
35
|
+
ruby_core_source (>= 0.1.4)
|
36
|
+
mongo (1.3.1)
|
37
|
+
bson (>= 1.3.1)
|
38
|
+
mongoid-rspec (1.4.4)
|
39
|
+
mongoid (~> 2.0)
|
40
|
+
rspec (~> 2)
|
41
|
+
multi_json (1.0.3)
|
42
|
+
rake (0.9.2)
|
43
|
+
rspec (2.6.0)
|
44
|
+
rspec-core (~> 2.6.0)
|
45
|
+
rspec-expectations (~> 2.6.0)
|
46
|
+
rspec-mocks (~> 2.6.0)
|
47
|
+
rspec-core (2.6.4)
|
48
|
+
rspec-expectations (2.6.0)
|
49
|
+
diff-lcs (~> 1.1.2)
|
50
|
+
rspec-mocks (2.6.0)
|
51
|
+
ruby-debug-base19 (0.11.25)
|
52
|
+
columnize (>= 0.3.1)
|
53
|
+
linecache19 (>= 0.5.11)
|
54
|
+
ruby_core_source (>= 0.1.4)
|
55
|
+
ruby-debug19 (0.11.6)
|
56
|
+
columnize (>= 0.3.1)
|
57
|
+
linecache19 (>= 0.5.11)
|
58
|
+
ruby-debug-base19 (>= 0.11.19)
|
59
|
+
ruby_core_source (0.1.5)
|
60
|
+
archive-tar-minitar (>= 0.5.2)
|
61
|
+
tzinfo (0.3.29)
|
62
|
+
|
63
|
+
PLATFORMS
|
64
|
+
ruby
|
65
|
+
|
66
|
+
DEPENDENCIES
|
67
|
+
activemodel (= 3.1.0.rc4)
|
68
|
+
bson_ext
|
69
|
+
database_cleaner
|
70
|
+
jeweler
|
71
|
+
mongoid!
|
72
|
+
mongoid-rspec
|
73
|
+
rspec
|
74
|
+
ruby-debug19
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rake'
|
10
|
+
require 'rdoc/task'
|
11
|
+
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'TranslationPanel'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'jeweler'
|
28
|
+
Jeweler::Tasks.new do |gem|
|
29
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
30
|
+
gem.name = "mongoid_globalize"
|
31
|
+
gem.homepage = "http://github.com/Mik-die/mongoid_globalize"
|
32
|
+
gem.license = "MIT"
|
33
|
+
gem.summary = %Q{Library for translating Mongoid documents}
|
34
|
+
gem.description = %Q{Library for translating Mongoid documents, based on Globalize3 principles}
|
35
|
+
gem.email = "MikDiet@gmail.com"
|
36
|
+
gem.authors = ["Mik-die"]
|
37
|
+
# dependencies defined in Gemfile
|
38
|
+
end
|
39
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module ActMacro
|
3
|
+
# TODO: other interface of +translates+. Like this:
|
4
|
+
# translates do
|
5
|
+
# field :title
|
6
|
+
# field :visible, type: Boolean
|
7
|
+
# end
|
8
|
+
def translates(*attr_names_or_hashes)
|
9
|
+
attr_hash = attr_names_or_hashes.inject({}) do |hash,attr|
|
10
|
+
hash.merge(attr.is_a?(Hash) ? attr : {attr => String})
|
11
|
+
end
|
12
|
+
attr_hash.each do |name, type|
|
13
|
+
self.translated_attribute_names.push name.to_sym
|
14
|
+
translated_attr_accessor(name)
|
15
|
+
translation_class.field name, type: type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fallbacks_for_empty_translations!
|
20
|
+
self.fallbacks_for_empty_translations = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
class Adapter
|
3
|
+
attr_accessor :record, :stash, :translations
|
4
|
+
private :record=, :stash=
|
5
|
+
|
6
|
+
def initialize(record)
|
7
|
+
self.record = record
|
8
|
+
self.stash = Attributes.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_stash(locale, name)
|
12
|
+
value = stash.read(locale, name)
|
13
|
+
return value if value
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(locale, name)
|
18
|
+
Mongoid::Globalize.fallbacks(locale).each do |fallback|
|
19
|
+
value = fetch_stash(fallback, name) || fetch_attribute(fallback, name)
|
20
|
+
unless fallbacks_for?(value)
|
21
|
+
set_metadata(value, :locale => fallback, :requested_locale => locale)
|
22
|
+
return value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def write(locale, name, value)
|
29
|
+
stash.write(locale, name, value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_translations!
|
33
|
+
stash.each do |locale, attrs|
|
34
|
+
translation = record.translations.find_or_initialize_by_locale(locale.to_s)
|
35
|
+
attrs.each{ |name, value| translation[name] = value }
|
36
|
+
translation.save!
|
37
|
+
end
|
38
|
+
# TODO: it's actual for mongoid?
|
39
|
+
#record.translations.reset
|
40
|
+
reset
|
41
|
+
end
|
42
|
+
|
43
|
+
def prepare_translations!
|
44
|
+
stash.each do |locale, attrs|
|
45
|
+
translation = record.translations.find_or_initialize_by_locale(locale.to_s)
|
46
|
+
attrs.each{ |name, value| translation[name] = value }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset
|
51
|
+
stash.clear
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def fetch_attribute(locale, name)
|
56
|
+
translation = record.translation_for(locale)
|
57
|
+
return translation && translation.send(name)
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_metadata(object, metadata)
|
61
|
+
object.translation_metadata.merge!(meta_data) if object.respond_to?(:translation_metadata)
|
62
|
+
object
|
63
|
+
end
|
64
|
+
|
65
|
+
def fallbacks_for?(object)
|
66
|
+
object.nil? || (fallbacks_for_empty_translations? && object.blank?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fallbacks_for_empty_translations?
|
70
|
+
record.fallbacks_for_empty_translations
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Helper class for storing values per locale. Used by Mongoid::Globalize::Adapter
|
2
|
+
# to stash and cache attribute values.
|
3
|
+
|
4
|
+
module Mongoid::Globalize
|
5
|
+
class Attributes < Hash # TODO: Think about using HashWithIndifferentAccess ?
|
6
|
+
def [](locale)
|
7
|
+
locale = locale.to_sym
|
8
|
+
self[locale] = {} unless has_key?(locale)
|
9
|
+
self.fetch(locale)
|
10
|
+
end
|
11
|
+
|
12
|
+
def contains?(locale, name)
|
13
|
+
self[locale].has_key?(name.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(locale, name)
|
17
|
+
self[locale][name.to_s]
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(locale, name, value)
|
21
|
+
#raise 'z' if value.nil? # TODO
|
22
|
+
self[locale][name.to_s] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module ClassMethods
|
3
|
+
delegate :translated_locales, :to => :translation_class
|
4
|
+
|
5
|
+
# TODO: At first deal with +translated_locales+
|
6
|
+
#
|
7
|
+
#def with_locales(*locales)
|
8
|
+
# scoped.merge(translation_class.with_locales(*locales))
|
9
|
+
#end
|
10
|
+
#
|
11
|
+
#def with_translations(*locales)
|
12
|
+
# locales = translated_locales if locales.empty?
|
13
|
+
# includes(:translations).with_locales(locales).with_required_attributes
|
14
|
+
#end
|
15
|
+
#
|
16
|
+
#def with_required_attributes
|
17
|
+
# required_translated_attributes.inject(scoped) do |scope, name|
|
18
|
+
# scope.where("#{translated_column_name(name)} IS NOT NULL")
|
19
|
+
# end
|
20
|
+
#end
|
21
|
+
#
|
22
|
+
#def with_translated_attribute(name, value, locales = nil)
|
23
|
+
# locales ||= Globalize.fallbacks
|
24
|
+
# with_translations.where(
|
25
|
+
# translated_column_name(name) => value,
|
26
|
+
# translated_column_name(:locale) => Array(locales).map(&:to_s)
|
27
|
+
# )
|
28
|
+
#end
|
29
|
+
|
30
|
+
def translated?(name)
|
31
|
+
translated_attribute_names.include?(name.to_sym)
|
32
|
+
end
|
33
|
+
|
34
|
+
def required_attributes
|
35
|
+
validators.map{ |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten.compact
|
36
|
+
end
|
37
|
+
|
38
|
+
def required_translated_attributes
|
39
|
+
translated_attribute_names & required_attributes
|
40
|
+
end
|
41
|
+
|
42
|
+
def translation_class
|
43
|
+
@translation_class ||= begin
|
44
|
+
klass = self.const_get(:Translation) rescue nil
|
45
|
+
if klass.nil?
|
46
|
+
klass = self.const_set(:Translation, Class.new(Mongoid::Globalize::DocumentTranslation))
|
47
|
+
end
|
48
|
+
klass.embedded_in name.underscore.gsub('/', '_')
|
49
|
+
klass
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def translated_attr_accessor(name)
|
55
|
+
define_method(:"#{name}=") do |value|
|
56
|
+
write_attribute(name, value)
|
57
|
+
end
|
58
|
+
define_method(name) do |*args|
|
59
|
+
read_attribute(name, {:locale => args.first})
|
60
|
+
end
|
61
|
+
alias_method :"#{name}_before_type_cast", name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
class DocumentTranslation
|
3
|
+
include Mongoid::Document
|
4
|
+
field :locale
|
5
|
+
class << self
|
6
|
+
def with_locales(*locales)
|
7
|
+
locales = locales.flatten.map(&:to_s)
|
8
|
+
where(:locale.in => locales)
|
9
|
+
end
|
10
|
+
alias with_locale with_locales
|
11
|
+
|
12
|
+
def translated_locales
|
13
|
+
# TODO
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_or_initialize_by_locale(locale)
|
18
|
+
with_locale(locale.to_s).first || build(:locale => locale.to_s)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def locale
|
23
|
+
read_attribute(:locale).to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def locale=(locale)
|
27
|
+
write_attribute(:locale, locale.to_s)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Mongoid::Globalize
|
2
|
+
module InstanceMethods
|
3
|
+
delegate :translated_locales, :to => :translations
|
4
|
+
|
5
|
+
def globalize
|
6
|
+
@globalize ||= Adapter.new(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def attributes
|
10
|
+
if @stop_merging_translated_attributes
|
11
|
+
super
|
12
|
+
else
|
13
|
+
@attributes = super.merge translated_attributes
|
14
|
+
@attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def process(attributes, *args)
|
19
|
+
with_given_locale(attributes) { super }
|
20
|
+
end
|
21
|
+
|
22
|
+
# All of this replaced by #process.. may be :)
|
23
|
+
#def write_attributes(attributes, *args)
|
24
|
+
# with_given_locale(attributes) { super }
|
25
|
+
#end
|
26
|
+
|
27
|
+
#def update_attributes!(attributes, *args)
|
28
|
+
# with_given_locale(attributes) { super }
|
29
|
+
#end
|
30
|
+
#
|
31
|
+
#def update_attributes(attributes, *args)
|
32
|
+
# with_given_locale(attributes) { super }
|
33
|
+
#end
|
34
|
+
|
35
|
+
def write_attribute(name, value, options = {})
|
36
|
+
if translated?(name)
|
37
|
+
options = {:locale => nil}.merge(options)
|
38
|
+
access = name.to_s
|
39
|
+
unless attributes[access] == value || attribute_changed?(access)
|
40
|
+
attribute_will_change! access
|
41
|
+
end
|
42
|
+
globalize.write(options[:locale] || Mongoid::Globalize.locale, name, value)
|
43
|
+
else
|
44
|
+
super(name, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_attribute(name, options = {})
|
49
|
+
options = {:translated => true, :locale => nil}.merge(options)
|
50
|
+
if translated?(name) and options[:translated]
|
51
|
+
globalize.fetch(options[:locale] || Mongoid::Globalize.locale, name)
|
52
|
+
else
|
53
|
+
super(name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# TODO
|
58
|
+
def remove_attribute(name)
|
59
|
+
super name
|
60
|
+
end
|
61
|
+
|
62
|
+
# Mongoid documents haven't attribute_names method, so I replace +super+
|
63
|
+
# with +@attributes.keys.sort+. So this method returns only translated and
|
64
|
+
# existing attribute names (but not all available names as in AR or G3)
|
65
|
+
def attribute_names
|
66
|
+
translated_attribute_names.map(&:to_s) + @attributes.keys.sort
|
67
|
+
end
|
68
|
+
|
69
|
+
def translated?(name)
|
70
|
+
self.class.translated?(name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def translated_attributes
|
74
|
+
translated_attribute_names.inject({}) do |attributes, name|
|
75
|
+
attributes.merge(name.to_s => translation.send(name))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def untranslated_attributes
|
80
|
+
attrs = {}
|
81
|
+
attribute_names.each do |name|
|
82
|
+
attrs[name] = read_attribute(name, {:translated => false})
|
83
|
+
end
|
84
|
+
attrs
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_translations(options)
|
88
|
+
options.keys.each do |locale|
|
89
|
+
translation = translation_for(locale) || translations.build(:locale => locale.to_s)
|
90
|
+
translation.update_attributes!(options[locale])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def reload
|
95
|
+
translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
|
96
|
+
globalize.reset
|
97
|
+
super
|
98
|
+
end
|
99
|
+
|
100
|
+
def clone
|
101
|
+
obj = super
|
102
|
+
return obj unless respond_to?(:translated_attribute_names)
|
103
|
+
|
104
|
+
# obj.instance_variable_set(:@translations, nil) if new_record?
|
105
|
+
obj.instance_variable_set(:@globalize, nil )
|
106
|
+
each_locale_and_translated_attribute do |locale, name|
|
107
|
+
obj.globalize.write(locale, name, globalize.fetch(locale, name) )
|
108
|
+
end
|
109
|
+
return obj
|
110
|
+
end
|
111
|
+
|
112
|
+
def translation
|
113
|
+
translation_for(Mongoid::Globalize.locale)
|
114
|
+
end
|
115
|
+
|
116
|
+
def translation_for(locale)
|
117
|
+
@translation_caches ||= {}
|
118
|
+
unless @translation_caches[locale]
|
119
|
+
_translation = translations.detect{|t| t.locale.to_s == locale.to_s}
|
120
|
+
_translation ||= translations.build(:locale => locale)
|
121
|
+
@translation_caches[locale] = _translation
|
122
|
+
end
|
123
|
+
@translation_caches[locale]
|
124
|
+
end
|
125
|
+
|
126
|
+
protected
|
127
|
+
def each_locale_and_translated_attribute
|
128
|
+
used_locales.each do |locale|
|
129
|
+
translated_attribute_names.each do |name|
|
130
|
+
yield locale, name
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def used_locales
|
136
|
+
locales = globalize.stash.keys.concat(globalize.stash.keys).concat(translations.translated_locales)
|
137
|
+
locales.uniq!
|
138
|
+
locales
|
139
|
+
end
|
140
|
+
|
141
|
+
def unmerge_translations!
|
142
|
+
@stop_merging_translated_attributes = true
|
143
|
+
translated_attribute_names.each do |name|
|
144
|
+
@attributes.delete name.to_s
|
145
|
+
@changed_attributes.delete name.to_s
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def create_translations!
|
150
|
+
globalize.save_translations!
|
151
|
+
clear_translations!
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_translations!
|
155
|
+
unmerge_translations!
|
156
|
+
globalize.prepare_translations!
|
157
|
+
globalize.reset
|
158
|
+
end
|
159
|
+
|
160
|
+
def clear_translations!
|
161
|
+
@translation_caches = {}
|
162
|
+
@stop_merging_translated_attributes = nil
|
163
|
+
end
|
164
|
+
|
165
|
+
def with_given_locale(attributes, &block)
|
166
|
+
attributes.symbolize_keys! if attributes.respond_to?(:symbolize_keys!)
|
167
|
+
if locale = attributes.try(:delete, :locale)
|
168
|
+
Mongoid::Globalize.with_locale(locale, &block)
|
169
|
+
else
|
170
|
+
yield
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'mongoid_globalize/adapter'
|
2
|
+
require 'mongoid_globalize/act_macro'
|
3
|
+
require 'mongoid_globalize/attributes'
|
4
|
+
require 'mongoid_globalize/class_methods'
|
5
|
+
require 'mongoid_globalize/document_translation'
|
6
|
+
require 'mongoid_globalize/instance_methods'
|
7
|
+
|
8
|
+
module Mongoid::Globalize
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
included do
|
11
|
+
class_attribute :translated_attribute_names, :fallbacks_for_empty_translations
|
12
|
+
self.translated_attribute_names = []
|
13
|
+
embeds_many :translations, :class_name => translation_class.name
|
14
|
+
#:extend => HasManyExtensions
|
15
|
+
before_create :unmerge_translations!
|
16
|
+
after_create :create_translations!
|
17
|
+
before_update :update_translations!
|
18
|
+
after_create :clear_translations!
|
19
|
+
|
20
|
+
extend Mongoid::Globalize::ActMacro
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def locale
|
25
|
+
read_locale || I18n.locale
|
26
|
+
end
|
27
|
+
|
28
|
+
def locale=(locale)
|
29
|
+
set_locale(locale)
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_locale(locale, &block)
|
33
|
+
previous_locale = read_locale
|
34
|
+
set_locale(locale)
|
35
|
+
result = yield(locale)
|
36
|
+
set_locale(previous_locale)
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_locales(*locales, &block)
|
41
|
+
locales.flatten.map do |locale|
|
42
|
+
with_locale(locale, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def fallbacks?
|
47
|
+
I18n.respond_to?(:fallbacks)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fallbacks(locale = self.locale)
|
51
|
+
fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
def read_locale
|
56
|
+
Thread.current[:globalize_locale]
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_locale(locale)
|
60
|
+
Thread.current[:globalize_locale] = locale.to_sym rescue nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
#
|
64
|
+
#module HasManyExtensions
|
65
|
+
# def find_or_initialize_by_locale(locale)
|
66
|
+
# with_locale(locale.to_s).first || build(:locale => locale.to_s)
|
67
|
+
# end
|
68
|
+
#end
|
69
|
+
end
|