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 189
|
require 'fast_gettext/cache'
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 |value|
switch_cache if Thread.current[key] != Thread.current[key]=value
end
end
def _locale
Thread.current[:fast_gettext__locale]
end
private :_locale, :_locale=
def available_locales
locales = Thread.current[:fast_gettext_available_locales] || default_available_locales
return unless locales
locales.map{|s|s.to_s}
end
# cattr_accessor with defaults
[
[:default_available_locales, "nil"],
[:default_text_domain, "nil"],
[:cache_class, "FastGettext::Cache"]
].each do |name, default|
eval <<-Ruby
@@#{name} = #{default}
def #{name}=(value)
@@#{name} = value
switch_cache
end
def #{name}
@@#{name}
end
Ruby
end
def text_domain
Thread.current[:fast_gettext_text_domain] || default_text_domain
end
# if overwritten by user( FastGettext.pluralisation_rule = xxx) use it,
# otherwise fall back to repo or to default lambda
def pluralisation_rule
Thread.current[:fast_gettext_pluralisation_rule] || current_repository.pluralisation_rule || lambda{|i| i!=1}
end
def cache
Thread.current[:fast_gettext_cache] ||= cache_class.new
end
def reload!
cache.reload!
translation_repositories.values.each(&:reload)
end
#global, since re-parsing whole folders takes too much time...
@@translation_repositories={}
def translation_repositories
@@translation_repositories
end
def current_repository
translation_repositories[text_domain] || raise(NoTextDomainConfigured)
end
def key_exist?(key)
!!(cached_find key)
end
def cached_find(key)
cache.fetch(key) { current_repository[key] }
end
def cached_plural_find(*keys)
key = '||||' + keys * '||||'
cache.fetch(key) { current_repository.plural(*keys) }
end
def expire_cache_for(key)
cache.delete(key)
end
def locale
_locale || ( default_locale || (available_locales||[]).first || 'en' )
end
def locale=(new_locale)
set_locale(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)
new_locale = best_locale_in(new_locale)
self._locale = new_locale
locale
end
@@default_locale = nil
def default_locale=(new_locale)
@@default_locale = best_locale_in(new_locale)
switch_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
# temporarily switch locale for a block
# FastGettext.with_locale 'xx' { _('cars') }
def with_locale(temp_locale)
current_locale = locale
set_locale temp_locale
yield
ensure
set_locale current_locale
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', :path => 'locale')
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,3})[-_]([a-zA-Z]{2,3})$/){$1.downcase+'_'+$2.upcase}
end
def switch_cache
cache.switch_to(text_domain, locale)
end
end
end
|