babylonia 0.1.1 → 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.
- checksums.yaml +13 -5
- data/lib/babylonia/class_methods.rb +211 -135
- data/lib/babylonia/version.rb +1 -1
- metadata +9 -10
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YzYzMTcwNjBhNThmMTUxYzVkZWE3ZTcwMzM4ZjhmM2MxZWMxMmVlNg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YzkxZTg3YTc2YmY2NTFjMzdjMDIwYjg0OWQ3N2M0ZDA3OGE2MTkyMw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTUxYjJhYTJjY2Q4Nzg3NmIzMGY1YzYxZjJjYTA0NTJjNWM5ZjAwODUxMWUx
|
10
|
+
NzE4YjdlN2RjZGRlYWMzNjlhN2Q1ZjJiZGEyZDhmMGU2NTlhMzQyODk2YjQ3
|
11
|
+
ZWI5M2UwYmQwNDI5YzIxY2I1MzE0NGNjMGFkYWU1YzIzMWEwZWE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTZmMzRhYzIwYjg0MTA3YTAyOWY3NWIwNjgzYTY1Y2UxOWY1MmUzNTY2YTdj
|
14
|
+
ZmNiODU0NmY5MTNkNzU2ZDFmZTQxNzA5MmY5MGIzNjY1N2RiNDk0ZmM3ZDg1
|
15
|
+
MzA3YmI1NTM2MWFlMTllYWIyMTFjMDYxNzMxNzFlMTQ4ZTY4MDM=
|
@@ -3,164 +3,203 @@ require 'i18n'
|
|
3
3
|
|
4
4
|
# Let your users translate their content into their languages without additional tables or columns in your tables
|
5
5
|
# @author Beat Richartz
|
6
|
-
# @version 0.0
|
6
|
+
# @version 0.2.0
|
7
7
|
# @since 0.0.1
|
8
8
|
#
|
9
9
|
module Babylonia
|
10
10
|
|
11
|
-
#
|
11
|
+
# Helper Methods for locales
|
12
|
+
# @author Beat Richartz
|
13
|
+
# @version 0.0.2
|
14
|
+
# @since 0.0.1
|
12
15
|
#
|
13
|
-
module
|
14
|
-
#
|
15
|
-
# @
|
16
|
-
# @param [Hash] options The options for translation
|
17
|
-
# @option [Symbol, Proc, String] locale The current locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales or a proc that will get called with the instance. Defaults to I18n.locale at the time of use
|
18
|
-
# @option [Symbol, Proc, String] default_locale The fallback / default locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales, a proc that will get called with the instance
|
19
|
-
# @option [Symbol, Proc, Array] available_locales The available locales - can be either a symbol that will be sent to the instance, a proc that will get called with the instance, or an Array of symbols of available locales. Defaults to I18n.available_locales at the time of use.
|
20
|
-
# @option [Boolean] fallback Wheter to fallback to the default locale or not
|
21
|
-
# @option [String] placeholder The placeholder to use for missing translations
|
16
|
+
module HelperMethods
|
17
|
+
# Return the currently active locale for the object
|
18
|
+
# @return [Symbol] The currently active locale
|
22
19
|
#
|
23
|
-
def
|
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
|
-
evaluate_localization_option!(:locale)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Return the default locale for the object
|
88
|
-
# @return [Symbol] The currently active locale
|
89
|
-
#
|
90
|
-
define_method :default_locale do
|
91
|
-
evaluate_localization_option!(:default_locale)
|
20
|
+
def locale
|
21
|
+
evaluate_localization_option!(:locale)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return the default locale for the object
|
25
|
+
# @return [Symbol] The currently active locale
|
26
|
+
#
|
27
|
+
def default_locale
|
28
|
+
evaluate_localization_option!(:default_locale)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return if the object falls back on translations
|
32
|
+
# @return [Boolean] if the translations fall back to the default locale
|
33
|
+
#
|
34
|
+
def locale_fallback?
|
35
|
+
evaluate_localization_option!(:fallback)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the missing translation placeholder
|
39
|
+
# @return [String] The missing translation placeholder
|
40
|
+
#
|
41
|
+
def missing_translation_placeholder field
|
42
|
+
evaluate_localization_option!(:placeholder, field)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return if a translation in the language is stored in all translated fields
|
46
|
+
# @return [Boolean] True if a translation is stored
|
47
|
+
#
|
48
|
+
def has_locale? locale
|
49
|
+
locales.include?(locale.to_sym)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return all the available locales
|
53
|
+
# @return [Array] An array of symbols of all available locales
|
54
|
+
#
|
55
|
+
def available_locales
|
56
|
+
evaluate_localization_option!(:available_locales)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return if a locale is theoretically available in all translated fields
|
60
|
+
# @return [Boolean] True if the language is available
|
61
|
+
#
|
62
|
+
def has_available_locale? locale
|
63
|
+
available_locales.include?(locale.to_sym)
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def translation_nil_or_empty? translation
|
69
|
+
translation.nil? or translation.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
def dump_translation_locale_hash hash
|
73
|
+
YAML.dump(hash.delete_if{|k,v| translation_nil_or_empty?(v) })
|
74
|
+
end
|
75
|
+
|
76
|
+
def fallback_to_default_locale!(hash, translation, options)
|
77
|
+
if translation_nil_or_empty?(translation) and options[:fallback] and locale_fallback?
|
78
|
+
hash[default_locale]
|
79
|
+
else
|
80
|
+
translation
|
92
81
|
end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Method missing implementation for virtual attributes
|
86
|
+
# @author Beat Richartz
|
87
|
+
# @version 0.0.2
|
88
|
+
# @since 0.0.1
|
89
|
+
#
|
90
|
+
module VirtualAttributes
|
91
|
+
# Define method missing to be able to access a language directly
|
92
|
+
# Enables to call a language virtual attribute directly
|
93
|
+
# @note Since the virtual attribute is called directly, there is no fallback on this unless you set it to true
|
94
|
+
# @example Call a getter directly
|
95
|
+
# object.field_de #=> 'DEUTSCH'
|
96
|
+
# @example Call a setter directly
|
97
|
+
# object.field_de = 'DEUTSCH'
|
98
|
+
# @example Call an untranslated field
|
99
|
+
# object.field_it #=> nil
|
100
|
+
#
|
101
|
+
# @example Call a field with fallback
|
102
|
+
# object.field_it(fallback: true)
|
103
|
+
def method_missing meth, *args, &block
|
104
|
+
if parts = extract_locale_method_parts(meth)
|
105
|
+
parts[2] ? send(parts[0] + parts[2].to_s, { parts[1].to_sym => args.first }) : send(parts[0], parts[1].to_sym, args.first || {})
|
106
|
+
else
|
107
|
+
super(meth, *args, &block)
|
99
108
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def extract_locale_method_parts meth
|
114
|
+
if (parts = meth.to_s.match(/\A([^_]+)_(\w+)(=)?\z/).to_a[1..3]) && localized?(parts[0]) && has_available_locale?(parts[1])
|
115
|
+
parts
|
106
116
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Class methods to extend a class with in order to make it able to handle translatable attributes
|
121
|
+
#
|
122
|
+
module ClassMethods
|
123
|
+
private
|
124
|
+
|
125
|
+
def install_locale_field_getter_for(field)
|
126
|
+
# Alias method chain the field to a translated value
|
127
|
+
# @param [Symbol] locale Pass a locale to get the field translation in this specific locale
|
128
|
+
# @param [Boolean] fallback Whether a fallback should be used, defaults to true
|
129
|
+
# @return [String, NilClass] Either the string with the translation, the fallback, the placeholder or nil
|
130
|
+
# @example Call a field in italian
|
131
|
+
# your_instance.field(:it) #=> "Translation"
|
110
132
|
#
|
111
|
-
define_method :
|
112
|
-
|
113
|
-
|
133
|
+
define_method :"#{field}_translated" do |l=nil, options={fallback: true}|
|
134
|
+
field_hash = send(:"#{field}_hash")
|
135
|
+
translation = field_hash[l || locale]
|
136
|
+
translation = fallback_to_default_locale!(field_hash, translation, options)
|
137
|
+
translation_nil_or_empty?(translation) ? missing_translation_placeholder(field) : translation
|
114
138
|
end
|
115
|
-
|
116
|
-
|
117
|
-
|
139
|
+
alias_method :"#{field}_raw", field
|
140
|
+
alias_method field, :"#{field}_translated"
|
141
|
+
end
|
142
|
+
|
143
|
+
def install_locale_field_hash_for(field)
|
144
|
+
# Return the translated values as a hash
|
145
|
+
# @return [Hash] The hash with all the translations stored in the field
|
118
146
|
#
|
119
|
-
define_method :
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
# Return all the available locales
|
124
|
-
# @return [Array] An array of symbols of all available locales
|
125
|
-
#
|
126
|
-
define_method :available_locales do
|
127
|
-
evaluate_localization_option!(:available_locales)
|
147
|
+
define_method :"#{field}_hash" do
|
148
|
+
field_content = send(:"#{field}_raw")
|
149
|
+
field_content.is_a?(String) ? YAML.load(field_content) : {}
|
128
150
|
end
|
129
|
-
|
130
|
-
|
131
|
-
|
151
|
+
end
|
152
|
+
|
153
|
+
def install_locale_field_setter_for(field)
|
154
|
+
# Set the field to a value. This either takes a string or a hash
|
155
|
+
# If given a String, the current locale is set to this value
|
156
|
+
# If given a Hash, the hash is merged into the current translation hash, and empty values are purged
|
157
|
+
# @param [String, Hash] data The data to set either the current language translation or all translations to
|
158
|
+
# @example Set the translation for the current locale
|
159
|
+
# your_object.field = "TRANSLATION"
|
160
|
+
# @example Set the translation and delete italian
|
161
|
+
# your_object.field = {de: 'DEUTSCH', it: ''}
|
132
162
|
#
|
133
|
-
define_method :
|
134
|
-
|
163
|
+
define_method :"#{field}_translated=" do |data|
|
164
|
+
current_hash = send(:"#{field}_hash")
|
165
|
+
|
166
|
+
if data.is_a?(String)
|
167
|
+
current_hash.merge! locale => data
|
168
|
+
elsif data.is_a?(Hash)
|
169
|
+
data.delete_if{|k,v| !has_available_locale?(k) }
|
170
|
+
current_hash.merge! data
|
171
|
+
end
|
172
|
+
|
173
|
+
send(:"#{field}_raw=", dump_translation_locale_hash(current_hash))
|
135
174
|
end
|
136
|
-
|
175
|
+
alias_method :"#{field}_raw=", :"#{field}="
|
176
|
+
alias_method :"#{field}=", :"#{field}_translated="
|
177
|
+
end
|
178
|
+
|
179
|
+
def install_virtual_locale_attributes_via_method_missing
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
def install_localized_helper_for(fields)
|
137
184
|
# Return if an attribute is localized
|
138
185
|
# @return [Boolean] True if the attribute is localized
|
139
186
|
#
|
140
187
|
define_method :localized? do |attr|
|
141
188
|
fields.include?(attr.to_sym)
|
142
189
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
#
|
147
|
-
# @
|
148
|
-
# object.field_de #=> 'DEUTSCH'
|
149
|
-
# @example Call a setter directly
|
150
|
-
# object.field_de = 'DEUTSCH'
|
151
|
-
# @example Call an untranslated field
|
152
|
-
# object.field_it #=> nil
|
190
|
+
end
|
191
|
+
|
192
|
+
def install_locales_helper_for(fields)
|
193
|
+
# Return languages stored in all translated fields
|
194
|
+
# @return [Array] An array containing all languages stored
|
153
195
|
#
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
if (m = meth.to_s.match(/\A([^_]+)_(\w+)(=)?\z/).to_a[1..3]) && localized?(m[0]) && has_available_locale?(m[1])
|
158
|
-
m[2] ? send(m[0] + m[2].to_s, {m[1].to_sym => args.first}) : send(m[0], m[1].to_sym, args.first || {})
|
159
|
-
else
|
160
|
-
super(meth, *args, &block)
|
161
|
-
end
|
196
|
+
define_method :locales do
|
197
|
+
first_field_locales = send(:"#{fields.first}_hash").keys
|
198
|
+
fields.inject(first_field_locales){|o, f| o & send(:"#{f}_hash").keys }
|
162
199
|
end
|
163
|
-
|
200
|
+
end
|
201
|
+
|
202
|
+
def install_locale_options_evaluation(options)
|
164
203
|
# Evaluate a localization option
|
165
204
|
#
|
166
205
|
define_method :evaluate_localization_option! do |option, field=nil, recursion=false|
|
@@ -176,5 +215,42 @@ module Babylonia
|
|
176
215
|
end
|
177
216
|
end
|
178
217
|
end
|
218
|
+
|
219
|
+
def evaluate_locale_options_for(fields)
|
220
|
+
options = fields.last.is_a?(Hash) ? fields.pop : {}
|
221
|
+
options[:locale] ||= lambda { |r| I18n.locale }
|
222
|
+
options[:default_locale] ||= lambda { |r| I18n.default_locale }
|
223
|
+
options[:available_locales] ||= lambda { |r| I18n.available_locales }
|
224
|
+
options[:fallback] = true if options[:fallback].nil?
|
225
|
+
options
|
226
|
+
end
|
227
|
+
|
228
|
+
# Main class method ob Babylonia. Use to make attributes translatable
|
229
|
+
# @param [Symbol] fields the attributes to translate
|
230
|
+
# @param [Hash] options The options for translation
|
231
|
+
# @option [Symbol, Proc, String] locale The current locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales or a proc that will get called with the instance. Defaults to I18n.locale at the time of use
|
232
|
+
# @option [Symbol, Proc, String] default_locale The fallback / default locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales, a proc that will get called with the instance
|
233
|
+
# @option [Symbol, Proc, Array] available_locales The available locales - can be either a symbol that will be sent to the instance, a proc that will get called with the instance, or an Array of symbols of available locales. Defaults to I18n.available_locales at the time of use.
|
234
|
+
# @option [Boolean] fallback Wheter to fallback to the default locale or not
|
235
|
+
# @option [String] placeholder The placeholder to use for missing translations
|
236
|
+
#
|
237
|
+
public
|
238
|
+
|
239
|
+
def build_babylonian_tower_on(*fields)
|
240
|
+
options = evaluate_locale_options_for(fields)
|
241
|
+
|
242
|
+
fields.each do |field|
|
243
|
+
install_locale_field_getter_for(field)
|
244
|
+
install_locale_field_setter_for(field)
|
245
|
+
install_locale_field_hash_for(field)
|
246
|
+
end
|
247
|
+
|
248
|
+
include HelperMethods
|
249
|
+
install_localized_helper_for(fields)
|
250
|
+
install_locales_helper_for(fields)
|
251
|
+
|
252
|
+
include VirtualAttributes
|
253
|
+
install_locale_options_evaluation(options)
|
254
|
+
end
|
179
255
|
end
|
180
256
|
end
|
data/lib/babylonia/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: babylonia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Beat Richartz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - '>='
|
17
|
+
- - ! '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.5.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - '>='
|
24
|
+
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.5.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.0.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.0.0
|
41
41
|
description: Let your users translate their content into their languages without additional
|
@@ -70,21 +70,20 @@ require_paths:
|
|
70
70
|
- lib
|
71
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - '>='
|
73
|
+
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- - '>='
|
78
|
+
- - ! '>='
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 2.
|
83
|
+
rubygems_version: 2.1.11
|
84
84
|
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: Let there be languages!
|
87
87
|
test_files:
|
88
88
|
- spec/babylonia/class_methods_spec.rb
|
89
89
|
- spec/spec_helper.rb
|
90
|
-
has_rdoc:
|