fast_gettext 1.8.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +5 -3
- data/LICENSE +78 -0
- data/Readme.md +142 -51
- data/lib/fast_gettext/cache.rb +4 -2
- data/lib/fast_gettext/mo_file.rb +29 -19
- data/lib/fast_gettext/po_file.rb +17 -14
- data/lib/fast_gettext/storage.rb +38 -32
- data/lib/fast_gettext/translation.rb +79 -113
- data/lib/fast_gettext/translation_repository/base.rb +9 -6
- data/lib/fast_gettext/translation_repository/chain.rb +11 -5
- data/lib/fast_gettext/translation_repository/db.rb +12 -13
- data/lib/fast_gettext/translation_repository/db_models/translation_key.rb +11 -8
- data/lib/fast_gettext/translation_repository/db_models/translation_text.rb +4 -2
- data/lib/fast_gettext/translation_repository/logger.rb +4 -2
- data/lib/fast_gettext/translation_repository/merge.rb +9 -4
- data/lib/fast_gettext/translation_repository/mo.rb +8 -4
- data/lib/fast_gettext/translation_repository/po.rb +5 -2
- data/lib/fast_gettext/translation_repository/yaml.rb +10 -4
- data/lib/fast_gettext/translation_repository.rb +5 -5
- data/lib/fast_gettext/version.rb +3 -1
- data/lib/fast_gettext.rb +16 -16
- metadata +52 -10
data/lib/fast_gettext/storage.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fast_gettext/cache'
|
2
4
|
|
3
5
|
module FastGettext
|
@@ -12,11 +14,15 @@ module FastGettext
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
17
|
+
DEFAULT_PLURALIZATION_RULE = ->(i) { i != 1 }
|
18
|
+
|
15
19
|
[:available_locales, :_locale, :text_domain, :pluralisation_rule].each do |method_name|
|
16
|
-
key = "fast_gettext_#{method_name}"
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
key = "fast_gettext_#{method_name}"
|
21
|
+
eval <<-RUBY, nil, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
|
22
|
+
def #{method_name}=(value)
|
23
|
+
switch_cache if Thread.current[:#{key}] != Thread.current[:#{key}] = value
|
24
|
+
end
|
25
|
+
RUBY
|
20
26
|
end
|
21
27
|
|
22
28
|
def _locale
|
@@ -24,11 +30,11 @@ module FastGettext
|
|
24
30
|
end
|
25
31
|
private :_locale, :_locale=
|
26
32
|
|
27
|
-
|
28
33
|
def available_locales
|
29
34
|
locales = Thread.current[:fast_gettext_available_locales] || default_available_locales
|
30
35
|
return unless locales
|
31
|
-
|
36
|
+
|
37
|
+
locales.map(&:to_s)
|
32
38
|
end
|
33
39
|
|
34
40
|
# cattr_accessor with defaults
|
@@ -37,7 +43,7 @@ module FastGettext
|
|
37
43
|
[:default_text_domain, "nil"],
|
38
44
|
[:cache_class, "FastGettext::Cache"]
|
39
45
|
].each do |name, default|
|
40
|
-
eval <<-
|
46
|
+
eval <<-RUBY, nil, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
|
41
47
|
@@#{name} = #{default}
|
42
48
|
def #{name}=(value)
|
43
49
|
@@#{name} = value
|
@@ -47,7 +53,7 @@ module FastGettext
|
|
47
53
|
def #{name}
|
48
54
|
@@#{name}
|
49
55
|
end
|
50
|
-
|
56
|
+
RUBY
|
51
57
|
end
|
52
58
|
|
53
59
|
def text_domain
|
@@ -57,7 +63,7 @@ module FastGettext
|
|
57
63
|
# if overwritten by user( FastGettext.pluralisation_rule = xxx) use it,
|
58
64
|
# otherwise fall back to repo or to default lambda
|
59
65
|
def pluralisation_rule
|
60
|
-
Thread.current[:fast_gettext_pluralisation_rule] ||
|
66
|
+
Thread.current[:fast_gettext_pluralisation_rule] || current_repository.pluralisation_rule || DEFAULT_PLURALIZATION_RULE
|
61
67
|
end
|
62
68
|
|
63
69
|
def cache
|
@@ -69,8 +75,8 @@ module FastGettext
|
|
69
75
|
translation_repositories.values.each(&:reload)
|
70
76
|
end
|
71
77
|
|
72
|
-
#global, since re-parsing whole folders takes too much time...
|
73
|
-
@@translation_repositories={}
|
78
|
+
# global, since re-parsing whole folders takes too much time...
|
79
|
+
@@translation_repositories = {} # rubocop:disable Style/ClassVars
|
74
80
|
def translation_repositories
|
75
81
|
@@translation_repositories
|
76
82
|
end
|
@@ -97,7 +103,7 @@ module FastGettext
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def locale
|
100
|
-
_locale || (
|
106
|
+
_locale || (default_locale || (available_locales || []).first || 'en')
|
101
107
|
end
|
102
108
|
|
103
109
|
def locale=(new_locale)
|
@@ -107,15 +113,15 @@ module FastGettext
|
|
107
113
|
# for chaining: puts set_locale('xx') == 'xx' ? 'applied' : 'rejected'
|
108
114
|
# returns the current locale, not the one that was supplied
|
109
115
|
# like locale=(), whoes behavior cannot be changed
|
110
|
-
def set_locale(new_locale)
|
116
|
+
def set_locale(new_locale) # rubocop:disable Naming/AccessorMethodName
|
111
117
|
new_locale = best_locale_in(new_locale)
|
112
118
|
self._locale = new_locale
|
113
119
|
locale
|
114
120
|
end
|
115
121
|
|
116
|
-
@@default_locale = nil
|
122
|
+
@@default_locale = nil # rubocop:disable Style/ClassVars
|
117
123
|
def default_locale=(new_locale)
|
118
|
-
@@default_locale = best_locale_in(new_locale)
|
124
|
+
@@default_locale = best_locale_in(new_locale) # rubocop:disable Style/ClassVars
|
119
125
|
switch_cache
|
120
126
|
end
|
121
127
|
|
@@ -123,17 +129,17 @@ module FastGettext
|
|
123
129
|
@@default_locale
|
124
130
|
end
|
125
131
|
|
126
|
-
#Opera: de-DE,de;q=0.9,en;q=0.8
|
127
|
-
#Firefox de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
|
128
|
-
#IE6/7 de
|
129
|
-
#nil if nothing matches
|
132
|
+
# Opera: de-DE,de;q=0.9,en;q=0.8
|
133
|
+
# Firefox de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
|
134
|
+
# IE6/7 de
|
135
|
+
# nil if nothing matches
|
130
136
|
def best_locale_in(locales)
|
131
137
|
formatted_sorted_locales(locales).each do |candidate|
|
132
|
-
return candidate
|
138
|
+
return candidate unless available_locales
|
133
139
|
return candidate if available_locales.include?(candidate)
|
134
|
-
return candidate[0..1] if available_locales.include?(candidate[0..1])#available locales include a langauge
|
140
|
+
return candidate[0..1] if available_locales.include?(candidate[0..1]) # available locales include a langauge
|
135
141
|
end
|
136
|
-
|
142
|
+
nil # nothing found im sorry :P
|
137
143
|
end
|
138
144
|
|
139
145
|
# temporarily switch locale for a block
|
@@ -146,27 +152,27 @@ module FastGettext
|
|
146
152
|
set_locale current_locale
|
147
153
|
end
|
148
154
|
|
149
|
-
#turn off translation if none was defined to disable all resulting errors
|
155
|
+
# turn off translation if none was defined to disable all resulting errors
|
150
156
|
def silence_errors
|
151
157
|
require 'fast_gettext/translation_repository/base'
|
152
|
-
translation_repositories[text_domain] ||= TranslationRepository::Base.new('x', :
|
158
|
+
translation_repositories[text_domain] ||= TranslationRepository::Base.new('x', path: 'locale')
|
153
159
|
end
|
154
160
|
|
155
161
|
private
|
156
162
|
|
157
163
|
# de-de,DE-CH;q=0.9 -> ['de_DE','de_CH']
|
158
164
|
def formatted_sorted_locales(locales)
|
159
|
-
found = weighted_locales(locales).reject
|
160
|
-
found.flatten.map{|l| format_locale(l)}
|
165
|
+
found = weighted_locales(locales).reject(&:empty?).sort_by(&:last).reverse # sort them by weight which is the last entry
|
166
|
+
found.flatten.map { |l| format_locale(l) }
|
161
167
|
end
|
162
168
|
|
163
|
-
#split the locale and seperate it into different languages
|
164
|
-
#de-de,de;q=0.9,en;q=0.8 => [['de-de','de','0.5'], ['en','0.8']]
|
169
|
+
# split the locale and seperate it into different languages
|
170
|
+
# de-de,de;q=0.9,en;q=0.8 => [['de-de','de','0.5'], ['en','0.8']]
|
165
171
|
def weighted_locales(locales)
|
166
|
-
locales = locales.to_s.gsub(/\s/,'')
|
172
|
+
locales = locales.to_s.gsub(/\s/, '')
|
167
173
|
found = [[]]
|
168
174
|
locales.split(',').each do |part|
|
169
|
-
if part
|
175
|
+
if part.include? ';q=' # contains language and weight ?
|
170
176
|
found.last << part.split(/;q=/)
|
171
177
|
found.last.flatten!
|
172
178
|
found << []
|
@@ -177,9 +183,9 @@ module FastGettext
|
|
177
183
|
found
|
178
184
|
end
|
179
185
|
|
180
|
-
#de-de -> de_DE
|
186
|
+
# de-de -> de_DE
|
181
187
|
def format_locale(locale)
|
182
|
-
locale.sub(/^([a-zA-Z]{2,3})[-_]([a-zA-Z]{2,3})$/){$1.downcase+'_'
|
188
|
+
locale.sub(/^([a-zA-Z]{2,3})[-_]([a-zA-Z]{2,3})$/) { $1.downcase + '_' + $2.upcase }
|
183
189
|
end
|
184
190
|
|
185
191
|
def switch_cache
|
@@ -1,4 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FastGettext
|
4
|
+
TRANSLATION_METHODS = [:_, :n_, :s_, :p_, :ns_, :np_].freeze
|
5
|
+
NIL_BLOCK = -> { nil }
|
6
|
+
|
2
7
|
# this module should be included
|
3
8
|
# Responsibility:
|
4
9
|
# - direct translation queries to the current repository
|
@@ -6,153 +11,114 @@ module FastGettext
|
|
6
11
|
# - understand / enforce namespaces
|
7
12
|
# - decide which plural form is used
|
8
13
|
module Translation
|
9
|
-
|
10
|
-
|
11
|
-
#make it usable in class definition, e.g.
|
12
|
-
# class Y
|
13
|
-
# include FastGettext::Translation
|
14
|
-
# @@x = _('y')
|
15
|
-
# end
|
16
|
-
def self.included(klas) #:nodoc:
|
17
|
-
klas.extend self
|
18
|
-
end
|
19
|
-
|
20
|
-
def _(key, &block)
|
21
|
-
FastGettext.cached_find(key) or (block ? block.call : key)
|
14
|
+
def _(key)
|
15
|
+
FastGettext.cached_find(key) || (block_given? ? yield : key)
|
22
16
|
end
|
23
17
|
|
24
|
-
#translate pluralized
|
18
|
+
# translate pluralized
|
25
19
|
# some languages have up to 4 plural forms...
|
26
20
|
# n_(singular, plural, plural form 2, ..., count)
|
27
21
|
# n_('apple','apples',3)
|
28
|
-
def n_(*keys,
|
29
|
-
count = keys.pop
|
22
|
+
def n_(*keys, count)
|
30
23
|
translations = FastGettext.cached_plural_find(*keys)
|
31
|
-
|
32
24
|
selected = FastGettext.pluralisation_rule.call(count)
|
33
|
-
selected = (selected ? 1 : 0) unless selected.is_a? Numeric #convert booleans to numbers
|
25
|
+
selected = (selected ? 1 : 0) unless selected.is_a? Numeric # convert booleans to numbers
|
34
26
|
|
27
|
+
# If we have a translation return it
|
35
28
|
result = translations[selected]
|
36
|
-
if result
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
29
|
+
return result if result
|
30
|
+
|
31
|
+
# If we have a block always use it in place of a translation
|
32
|
+
return yield if block_given?
|
33
|
+
|
34
|
+
# Fall back to the best fit translated key if it's there
|
35
|
+
_(keys[selected] || keys.last)
|
43
36
|
end
|
44
37
|
|
45
|
-
#translate with namespace
|
46
|
-
# 'Car','Tire' -> Tire if no translation could be found
|
47
|
-
# p_('Car','Tire')
|
48
|
-
def p_(namespace, key, separator=nil
|
49
|
-
msgid = "#{namespace}#{separator||
|
50
|
-
|
38
|
+
# translate with namespace
|
39
|
+
# 'Car', 'Tire' -> Tire if no translation could be found
|
40
|
+
# p_('Car', 'Tire') == s_('Car|Tire')
|
41
|
+
def p_(namespace, key, separator = nil)
|
42
|
+
msgid = "#{namespace}#{separator || CONTEXT_SEPARATOR}#{key}"
|
43
|
+
|
44
|
+
translation = FastGettext.cached_find(msgid)
|
45
|
+
return translation if translation
|
46
|
+
|
47
|
+
block_given? ? yield : key
|
51
48
|
end
|
52
49
|
|
53
|
-
#translate, but discard namespace if nothing was found
|
50
|
+
# translate, but discard namespace if nothing was found
|
54
51
|
# Car|Tire -> Tire if no translation could be found
|
55
|
-
def s_(key, separator=nil
|
56
|
-
translation = FastGettext.cached_find(key)
|
57
|
-
|
52
|
+
def s_(key, separator = nil)
|
53
|
+
translation = FastGettext.cached_find(key)
|
54
|
+
return translation if translation
|
55
|
+
|
56
|
+
block_given? ? yield : key.split(separator || NAMESPACE_SEPARATOR).last
|
58
57
|
end
|
59
58
|
|
60
|
-
#tell gettext: this string need translation (will be found during parsing)
|
59
|
+
# tell gettext: this string need translation (will be found during parsing)
|
61
60
|
def N_(translate)
|
62
61
|
translate
|
63
62
|
end
|
64
63
|
|
65
|
-
#tell gettext: this string need translation (will be found during parsing)
|
64
|
+
# tell gettext: this string need translation (will be found during parsing)
|
66
65
|
def Nn_(*keys)
|
67
66
|
keys
|
68
67
|
end
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
69
|
+
# translate pluralized with separator
|
70
|
+
def ns_(*args)
|
71
|
+
translation = n_(*args, &NIL_BLOCK)
|
72
|
+
return translation if translation
|
76
73
|
|
77
|
-
|
78
|
-
module TranslationMultidomain
|
79
|
-
extend self
|
80
|
-
|
81
|
-
#make it usable in class definition, e.g.
|
82
|
-
# class Y
|
83
|
-
# include FastGettext::TranslationMultidomain
|
84
|
-
# @@x = d_('domain', 'y')
|
85
|
-
# end
|
86
|
-
def self.included(klas) #:nodoc:
|
87
|
-
klas.extend self
|
88
|
-
end
|
74
|
+
return yield if block_given?
|
89
75
|
|
90
|
-
|
91
|
-
def _in_domain domain
|
92
|
-
old_domain = FastGettext.text_domain
|
93
|
-
FastGettext.text_domain = domain
|
94
|
-
yield if block_given?
|
95
|
-
ensure
|
96
|
-
FastGettext.text_domain = old_domain
|
76
|
+
n_(*args).split(NAMESPACE_SEPARATOR).last
|
97
77
|
end
|
98
78
|
|
99
|
-
#
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
def dn_(domain, *keys, &block)
|
107
|
-
_in_domain domain do
|
108
|
-
FastGettext::Translation.n_(*keys, &block)
|
109
|
-
end
|
110
|
-
end
|
79
|
+
# translate pluralized with context
|
80
|
+
def np_(context, plural_one, *args, separator: nil)
|
81
|
+
nargs = ["#{context}#{separator || CONTEXT_SEPARATOR}#{plural_one}"] + args
|
82
|
+
translation = n_(*nargs, &NIL_BLOCK)
|
83
|
+
return translation if translation
|
111
84
|
|
112
|
-
|
113
|
-
_in_domain domain do
|
114
|
-
FastGettext::Translation.s_(key, separator, &block)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def dns_(domain, *keys, &block)
|
119
|
-
_in_domain domain do
|
120
|
-
FastGettext::Translation.ns_(*keys, &block)
|
121
|
-
end
|
122
|
-
end
|
85
|
+
return yield if block_given?
|
123
86
|
|
124
|
-
|
125
|
-
# (note: if mutiple domains contains key, random translation is returned)
|
126
|
-
def D_(key)
|
127
|
-
FastGettext.translation_repositories.each_key do |domain|
|
128
|
-
result = FastGettext::TranslationMultidomain.d_(domain, key) {nil}
|
129
|
-
return result unless result.nil?
|
130
|
-
end
|
131
|
-
key
|
87
|
+
n_(plural_one, *args)
|
132
88
|
end
|
89
|
+
end
|
133
90
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
keys[-3].split(keys[-2]||NAMESPACE_SEPARATOR).last
|
140
|
-
end
|
91
|
+
module TranslationAliased
|
92
|
+
include Translation
|
93
|
+
TRANSLATION_METHODS.each { |m| alias_method "#{m.to_s.delete('_')}gettext", m }
|
94
|
+
end
|
141
95
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
return result unless result.nil?
|
146
|
-
end
|
147
|
-
key.split(separator||NAMESPACE_SEPARATOR).last
|
148
|
-
end
|
96
|
+
# this module should be included for multi-domain support
|
97
|
+
module TranslationMultidomain
|
98
|
+
include Translation
|
149
99
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
100
|
+
# gettext functions to translate in the context of given domain
|
101
|
+
TRANSLATION_METHODS.each do |method|
|
102
|
+
eval <<-RUBY, nil, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
|
103
|
+
# translate in given domain
|
104
|
+
def d#{method}(domain, *args, &block)
|
105
|
+
FastGettext.with_domain(domain) { #{method}(*args, &block) }
|
106
|
+
end
|
107
|
+
|
108
|
+
# translate with whatever domain finds a translation
|
109
|
+
def D#{method}(*args, &block)
|
110
|
+
repos = FastGettext.translation_repositories
|
111
|
+
last = repos.size - 1
|
112
|
+
repos.each_key.each_with_index do |domain, i|
|
113
|
+
if i == last
|
114
|
+
return d#{method}(domain, *args, &block)
|
115
|
+
else
|
116
|
+
result = d#{method}(domain, *args, &NIL_BLOCK)
|
117
|
+
return result if result
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
RUBY
|
156
122
|
end
|
157
123
|
end
|
158
124
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FastGettext
|
2
4
|
module TranslationRepository
|
3
5
|
# Responsibility:
|
4
6
|
# - base for all repositories
|
5
7
|
# - fallback as empty repository, that cannot translate anything but does not crash
|
6
8
|
class Base
|
7
|
-
|
8
9
|
attr_reader :name, :options
|
9
10
|
|
10
|
-
def initialize(name,options={})
|
11
|
+
def initialize(name, options = {})
|
11
12
|
@name = name
|
12
13
|
@options = options
|
13
14
|
end
|
@@ -38,17 +39,19 @@ module FastGettext
|
|
38
39
|
MoFile.empty
|
39
40
|
end
|
40
41
|
|
41
|
-
def find_files_in_locale_folders(relative_file_path,path)
|
42
|
+
def find_files_in_locale_folders(relative_file_path, path)
|
42
43
|
path ||= "locale"
|
43
44
|
raise "path #{path} could not be found!" unless File.exist?(path)
|
44
45
|
|
45
46
|
@files = {}
|
46
|
-
Dir[File.join(path,'*')].each do |locale_folder|
|
47
|
+
Dir[File.join(path, '*')].each do |locale_folder|
|
47
48
|
next unless File.basename(locale_folder) =~ LOCALE_REX
|
48
|
-
|
49
|
+
|
50
|
+
file = File.join(locale_folder, relative_file_path)
|
49
51
|
next unless File.exist? file
|
52
|
+
|
50
53
|
locale = File.basename(locale_folder)
|
51
|
-
@files[locale] = yield(locale,file)
|
54
|
+
@files[locale] = yield(locale, file)
|
52
55
|
end
|
53
56
|
end
|
54
57
|
end
|
@@ -1,32 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fast_gettext/translation_repository/base'
|
2
4
|
|
3
5
|
module FastGettext
|
4
6
|
module TranslationRepository
|
5
7
|
# Responsibility:
|
6
8
|
# - delegate calls to members of the chain in turn
|
7
|
-
#TODO cache should be expired after a repo was added
|
9
|
+
# TODO cache should be expired after a repo was added
|
8
10
|
class Chain < Base
|
9
11
|
attr_accessor :chain
|
10
12
|
|
11
|
-
def initialize(name,options={})
|
13
|
+
def initialize(name, options = {})
|
12
14
|
super
|
13
15
|
self.chain = options[:chain]
|
14
16
|
end
|
15
17
|
|
16
18
|
def available_locales
|
17
|
-
chain.map
|
19
|
+
chain.map(&:available_locales).flatten.uniq
|
18
20
|
end
|
19
21
|
|
20
22
|
def pluralisation_rule
|
21
23
|
chain.each do |c|
|
22
|
-
result = c.pluralisation_rule
|
24
|
+
if result = c.pluralisation_rule
|
25
|
+
return result
|
26
|
+
end
|
23
27
|
end
|
24
28
|
nil
|
25
29
|
end
|
26
30
|
|
27
31
|
def [](key)
|
28
32
|
chain.each do |c|
|
29
|
-
result = c[key]
|
33
|
+
if result = c[key]
|
34
|
+
return result
|
35
|
+
end
|
30
36
|
end
|
31
37
|
nil
|
32
38
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module FastGettext
|
3
4
|
module TranslationRepository
|
4
5
|
# Responsibility:
|
@@ -11,13 +12,14 @@ module FastGettext
|
|
11
12
|
# key: find_by_key, translations
|
12
13
|
# translation: text, locale
|
13
14
|
class Db
|
14
|
-
def initialize(
|
15
|
+
def initialize(_name, options = {})
|
15
16
|
@model = options[:model]
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
@separator = '||||' # string that separates multiple plurals
|
20
|
+
class << self
|
21
|
+
attr_accessor :separator
|
22
|
+
end
|
21
23
|
|
22
24
|
def available_locales
|
23
25
|
if @model.respond_to? :available_locales
|
@@ -28,11 +30,7 @@ module FastGettext
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def pluralisation_rule
|
31
|
-
if @model.respond_to? :
|
32
|
-
@model.pluralsation_rule
|
33
|
-
else
|
34
|
-
nil
|
35
|
-
end
|
33
|
+
@model.pluralisation_rule if @model.respond_to? :pluralisation_rule
|
36
34
|
end
|
37
35
|
|
38
36
|
def [](key)
|
@@ -40,8 +38,8 @@ module FastGettext
|
|
40
38
|
end
|
41
39
|
|
42
40
|
def plural(*args)
|
43
|
-
if translation = @model.translation(args*self.class.
|
44
|
-
translation.to_s.split(self.class.
|
41
|
+
if translation = @model.translation(args * self.class.separator, FastGettext.locale)
|
42
|
+
translation.to_s.split(self.class.separator)
|
45
43
|
else
|
46
44
|
[]
|
47
45
|
end
|
@@ -52,11 +50,12 @@ module FastGettext
|
|
52
50
|
end
|
53
51
|
|
54
52
|
def self.require_models
|
53
|
+
require 'active_record'
|
55
54
|
folder = "fast_gettext/translation_repository/db_models"
|
56
55
|
require "#{folder}/translation_key"
|
57
56
|
require "#{folder}/translation_text"
|
58
57
|
Module.new do
|
59
|
-
def self.included(
|
58
|
+
def self.included(_base)
|
60
59
|
puts "you no longer need to include the result of require_models"
|
61
60
|
end
|
62
61
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class TranslationKey < ActiveRecord::Base
|
2
|
-
has_many :translations, :
|
4
|
+
has_many :translations, class_name: 'TranslationText', dependent: :destroy
|
3
5
|
|
4
|
-
accepts_nested_attributes_for :translations, :
|
6
|
+
accepts_nested_attributes_for :translations, allow_destroy: true
|
5
7
|
|
6
8
|
validates_uniqueness_of :key
|
7
9
|
validates_presence_of :key
|
@@ -13,25 +15,26 @@ class TranslationKey < ActiveRecord::Base
|
|
13
15
|
def self.translation(key, locale)
|
14
16
|
return unless translation_key = find_by_key(newline_normalize(key))
|
15
17
|
return unless translation_text = translation_key.translations.find_by_locale(locale)
|
18
|
+
|
16
19
|
translation_text.text
|
17
20
|
end
|
18
21
|
|
19
22
|
def self.available_locales
|
20
|
-
|
23
|
+
@available_locales ||= begin
|
21
24
|
if ActiveRecord::VERSION::MAJOR >= 3
|
22
25
|
TranslationText.group(:locale).count
|
23
26
|
else
|
24
|
-
TranslationText.count(:
|
27
|
+
TranslationText.count(group: :locale)
|
25
28
|
end.keys.sort
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
def self.newline_normalize(s)
|
32
|
-
s.to_s.gsub("\r\n", "\n")
|
32
|
+
def self.newline_normalize(string)
|
33
|
+
string.to_s.gsub("\r\n", "\n")
|
33
34
|
end
|
34
35
|
|
36
|
+
protected
|
37
|
+
|
35
38
|
def normalize_newlines
|
36
39
|
self.key = self.class.newline_normalize(key)
|
37
40
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class TranslationText < ActiveRecord::Base
|
2
|
-
belongs_to :translation_key, :
|
4
|
+
belongs_to :translation_key, class_name: 'TranslationKey'
|
3
5
|
validates_presence_of :locale
|
4
|
-
validates_uniqueness_of :locale, :
|
6
|
+
validates_uniqueness_of :locale, scope: :translation_key_id
|
5
7
|
attr_accessible :text, :locale, :translation_key, :translation_key_id if ActiveRecord::VERSION::MAJOR == 3 || defined?(ProtectedAttributes)
|
6
8
|
after_update :expire_cache
|
7
9
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fast_gettext/translation_repository/base'
|
2
4
|
|
3
5
|
module FastGettext
|
@@ -8,7 +10,7 @@ module FastGettext
|
|
8
10
|
class Logger < Base
|
9
11
|
attr_accessor :callback
|
10
12
|
|
11
|
-
def initialize(name,options={})
|
13
|
+
def initialize(name, options = {})
|
12
14
|
super
|
13
15
|
self.callback = options[:callback]
|
14
16
|
end
|
@@ -24,4 +26,4 @@ module FastGettext
|
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
27
|
-
end
|
29
|
+
end
|