storage.rb
5.47 KB
1
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
module FastGettext
# Responsibility:
# - store data threadsave
# - provide error messages when repositories are unconfigured
# - accept/reject locales that are set by the user
module Storage
class NoTextDomainConfigured < RuntimeError
def to_s
"Current textdomain (#{FastGettext.text_domain.inspect}) was not added, use FastGettext.add_text_domain !"
end
end
[:available_locales, :_locale, :text_domain, :pluralisation_rule].each do |method_name|
key = "fast_gettext_#{method_name}".to_sym
define_method method_name do
Thread.current[key]
end
define_method "#{method_name}=" do |value|
Thread.current[key]=value
update_current_cache
end
end
private :_locale, :_locale=
def available_locales
Thread.current[:fast_gettext_available_locales] || default_available_locales
end
# == cattr_accessor :default_available_locales
@@default_available_locales = nil
def default_available_locales=(avail_locales)
@@default_available_locales = avail_locales
update_current_cache
end
def default_available_locales
@@default_available_locales
end
def text_domain
Thread.current[:fast_gettext_text_domain] || default_text_domain
end
# == cattr_accessor :default_text_domain
@@default_text_domain = nil
def default_text_domain=(domain)
@@default_text_domain = domain
update_current_cache
end
def default_text_domain
@@default_text_domain
end
def pluralisation_rule
Thread.current[:fast_gettext_pluralisation_rule] || current_repository.pluralisation_rule || lambda{|i| i!=1}
end
def current_cache
Thread.current[:fast_gettext_current_cache] || {}
end
def current_cache=(cache)
Thread.current[:fast_gettext_current_cache] = cache
end
#global, since re-parsing whole folders takes too much time...
@@translation_repositories={}
def translation_repositories
@@translation_repositories
end
# used to speedup simple translations, does not work for pluralisation
# caches[text_domain][locale][key]=translation
@@caches={}
def caches
@@caches
end
def current_repository
translation_repositories[text_domain] || raise(NoTextDomainConfigured)
end
def key_exist?(key)
!!(cached_find key)
end
def cached_find(key)
translation = current_cache[key]
return translation if translation or translation == false #found or was not found before
current_cache[key] = current_repository[key] || false
end
def cached_plural_find(*keys)
key = '||||' + keys * '||||'
translation = current_cache[key]
return translation if translation or translation == false #found or was not found before
current_cache[key] = current_repository.plural(*keys) || false
end
def locale
_locale || ( default_locale || (available_locales||[]).first || 'en' )
end
def locale=(new_locale)
new_locale = best_locale_in(new_locale)
self._locale = new_locale if new_locale
end
# for chaining: puts set_locale('xx') == 'xx' ? 'applied' : 'rejected'
# returns the current locale, not the one that was supplied
# like locale=(), whoes behavior cannot be changed
def set_locale(new_locale)
self.locale = new_locale
locale
end
@@default_locale = nil
def default_locale=(new_locale)
@@default_locale = best_locale_in(new_locale)
update_current_cache
end
def default_locale
@@default_locale
end
#Opera: de-DE,de;q=0.9,en;q=0.8
#Firefox de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
#IE6/7 de
#nil if nothing matches
def best_locale_in(locales)
formatted_sorted_locales(locales).each do |candidate|
return candidate if not available_locales
return candidate if available_locales.include?(candidate)
return candidate[0..1] if available_locales.include?(candidate[0..1])#available locales include a langauge
end
return nil#nothing found im sorry :P
end
#turn off translation if none was defined to disable all resulting errors
def silence_errors
require 'fast_gettext/translation_repository/base'
translation_repositories[text_domain] = TranslationRepository::Base.new('x')
end
private
# de-de,DE-CH;q=0.9 -> ['de_DE','de_CH']
def formatted_sorted_locales(locales)
found = weighted_locales(locales).reject{|x|x.empty?}.sort_by{|l|l.last}.reverse #sort them by weight which is the last entry
found.flatten.map{|l| format_locale(l)}
end
#split the locale and seperate it into different languages
#de-de,de;q=0.9,en;q=0.8 => [['de-de','de','0.5'], ['en','0.8']]
def weighted_locales(locales)
locales = locales.to_s.gsub(/\s/,'')
found = [[]]
locales.split(',').each do |part|
if part =~ /;q=/ #contains language and weight ?
found.last << part.split(/;q=/)
found.last.flatten!
found << []
else
found.last << part
end
end
found
end
#de-de -> de_DE
def format_locale(locale)
locale.sub(/^([a-zA-Z]{2})[-_]([a-zA-Z]{2})$/){$1.downcase+'_'+$2.upcase}
end
def update_current_cache
caches[text_domain] ||= {}
caches[text_domain][locale] ||= {}
caches[text_domain][locale][""] = false #ignore gettext meta key when translating
self.current_cache = caches[text_domain][locale]
end
end
end