Class: R18n::I18n

Inherits:
Object
  • Object
show all
Defined in:
lib/r18n-core/i18n.rb

Overview

General class to i18n support in your application. It load Translation and Locale classes and create pretty way to use it.

To get translation you can use same with Translation way – use method with translation’s name or [name] method. Translations will be also loaded for default locale, sublocales from first in locales and general languages for dialects (it will load fr for fr_CA too).

Translations will loaded by loader object, which must have 2 methods:

  • available – return array of locales of available translations;

  • load(locale) – return Hash of translation.

If you will use default loader (R18n.default_loader) you can pass to I18n only constructor argument for loader:

R18n::I18n.new('en', R18n::Loader::YAML.new('dir/with/translations'))

is a same as:

R18n::I18n.new('en', 'dir/with/translations')

In translation file you can use strings, numbers, floats (any YAML types) and pluralizable values (!!pl). You can use params in string values, which you can replace in program. Just write %1, %2, etc and set it values as method arguments, when you will be get value.

You can use filters for some YAML type or for all strings. See R18n::Filters for details.

R18n contain translations for common words (such as “OK”, “Cancel”, etc) for most supported locales. See base/ dir.

Usage

translations/ru.yml

one: Один

translations/en.yml

one: One
two: Two

example.rb

i18n = R18n::I18n.new(['ru', 'en'], 'translations/')

i18n.one   #=> "Один"
i18n.two   #=> "Two"

i18n.locale.title        #=> "Русский"
i18n.locale.code         #=> "ru"
i18n.locale.ltr?         #=> true

i18n.l -11000.5          #=> "−11 000,5"
i18n.l Time.now          #=> "Вск, 21 сен 2008, 22:10:10 MSD"
i18n.l Time.now, :date   #=> "21.09.2008"
i18n.l Time.now, :time   #=> "22:10"
i18n.l Time.now, '%A'    #=> "Воскресенье"

i18n.yes    #=> "Yes"
i18n.ok     #=> "OK"
i18n.cancel #=> "Cancel"

Constant Summary collapse

@@default =
'en'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(locales, translation_places = nil, opts = {}) ⇒ I18n

Create i18n for locales with translations from translation_places and locales data. Translations will be also loaded for default locale, sublocales from first in locales and general languages for dialects (it will load fr for fr_CA too).

Locales must be a locale code (RFC 3066) or array, ordered by priority. Translation_places must be a string with path or array.



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
# File 'lib/r18n-core/i18n.rb', line 145

def initialize(locales, translation_places = nil, opts = {})
  locales = Array(locales)

  if not locales.empty? and Locale.exists? locales.first
    locales += Locale.load(locales.first).sublocales
  end
  locales << @@default
  locales.each_with_index do |locale, i|
    if locale =~ /[_-]/
      locales.insert(i + 1, locale.match(/([^_-]+)[_-]/)[1])
    end
  end
  locales.map! { |i| i.to_s.downcase }.uniq!
  @locales_codes = locales
  @locales = locales.map { |i| Locale.load(i) }

  if translation_places
    @original_places = translation_places
  else
    @original_places = R18n.extension_places
    @locale = @locales.first
  end

  @translation_places = self.class.convert_places(@original_places)

  if opts[:on_filters] or opts[:off_filters]
    @filters = CustomFilterList.new(opts[:on_filters], opts[:off_filters])
  else
    @filters = GlobalFilterList.instance
  end

  key = translation_cache_key
  if R18n.cache.has_key? key
    @locale, @translation = *R18n.cache[key]
  else
    reload!
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject

Return translation with special name.

Translation can contain variable part. Just set is as %1, %2, etc in translations file and set values in next params.



285
286
287
# File 'lib/r18n-core/i18n.rb', line 285

def [](name, *params)
  @translation[name, *params]
end

Instance Attribute Details

#localeObject (readonly)

First locale with locale file



136
137
138
# File 'lib/r18n-core/i18n.rb', line 136

def locale
  @locale
end

#localesObject (readonly)

User locales, ordered by priority



130
131
132
# File 'lib/r18n-core/i18n.rb', line 130

def locales
  @locales
end

#translation_placesObject (readonly)

Loaders with translations files



133
134
135
# File 'lib/r18n-core/i18n.rb', line 133

def translation_places
  @translation_places
end

Class Method Details

.convert_places(places) ⇒ Object

Load default loader for elements in places with only constructor argument.



119
120
121
122
123
124
125
126
127
# File 'lib/r18n-core/i18n.rb', line 119

def self.convert_places(places)
  Array(places).map! do |loader|
    if loader.respond_to? :available and loader.respond_to? :load
      loader
    else
      R18n.default_loader.new(loader)
    end
  end
end

.defaultObject

Get default locale code



97
98
99
# File 'lib/r18n-core/i18n.rb', line 97

def self.default
  @@default
end

.default=(locale) ⇒ Object

Set default locale code to use when any user locales willn’t be founded. It should has all translations and locale file.



92
93
94
# File 'lib/r18n-core/i18n.rb', line 92

def self.default=(locale)
  @@default = locale
end

.parse_http(str) ⇒ Object

Parse HTTP_ACCEPT_LANGUAGE and return array of user locales



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/r18n-core/i18n.rb', line 102

def self.parse_http(str)
  return [] if str.nil?
  locales = str.split(',')
  locales.map! do |locale|
    locale = locale.split ';q='
    if 1 == locale.size
      [locale[0], 1.0]
    else
      [locale[0], locale[1].to_f]
    end
  end
  locales.sort! { |a, b| b[1] <=> a[1] }
  locales.map! { |i| i[0] }
end

Instance Method Details

#[](name, *params) ⇒ Object Also known as: method_missing

Return translation with special name.

Translation can contain variable part. Just set is as %1, %2, etc in translations file and set values in next params.



282
283
284
# File 'lib/r18n-core/i18n.rb', line 282

def [](name, *params)
  @translation[name, *params]
end

#available_localesObject

Return Array of locales with available translations.



251
252
253
# File 'lib/r18n-core/i18n.rb', line 251

def available_locales
  @available ||= R18n.available_locales(@translation_places)
end

#filter_listObject

Return custom filters list



185
186
187
# File 'lib/r18n-core/i18n.rb', line 185

def filter_list
  @filters
end

#localize(object, format = nil, *params) ⇒ Object Also known as: l

Convert object to String, according to the rules of the current locale. It support Fixnum, Bignum, Float, Time, Date and DateTime.

For time classes you can set format in standard strftime form, :full (“01 Jule, 2009”), :human (“yesterday”), :standard (“07/01/09”) or :month for standalone month name. Default format is :standard.

i18n.l -12000.5         #=> "−12,000.5"
i18n.l Time.now         #=> "07/01/09 12:59"
i18n.l Time.now.to_date #=> "07/01/09"
i18n.l Time.now, :human #=> "now"
i18n.l Time.now, :full  #=> "Jule 1st, 2009 12:59"


268
269
270
# File 'lib/r18n-core/i18n.rb', line 268

def localize(object, format = nil, *params)
  locale.localize(object, format, self, *params)
end

#reload!Object

Reload translations.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/r18n-core/i18n.rb', line 201

def reload!
  @available = @available_codes = nil
  @translation_places = self.class.convert_places(@original_places)

  available_in_places = @translation_places.map { |i| [i, i.available] }
  available_in_extensions = R18n.extension_places.map {|i| [i, i.available]}

  unless @locale
    available_in_places.each do |place, available|
      @locales.each do |locale|
        if available.include? locale
          @locale = locale
          break
        end
      end
      break if @locale
    end
  end
  @locale ||= @locales.first
  unless @locale.supported?
    @locales.each do |locale|
      if locale.supported?
        @locale.base = locale
        break
      end
    end
  end

  @translation = Translation.new(@locale, '', :filters => @filters)
  @locales.each do |locale|
    loaded = false
    available_in_places.each do |place, available|
      if available.include? locale
        @translation.merge! place.load(locale), locale
        loaded = true
      end
    end
    if loaded
      available_in_extensions.each do |extension, available|
        if available.include? locale
          @translation.merge! extension.load(locale), locale
        end
      end
    end
  end

  R18n.cache[translation_cache_key] = [@locale, @translation]
end

#tObject

Return translations.



274
275
276
# File 'lib/r18n-core/i18n.rb', line 274

def t
  @translation
end

#translation_cache_keyObject

Return unique key for current locales in translation and places.



190
191
192
193
194
195
196
197
198
# File 'lib/r18n-core/i18n.rb', line 190

def translation_cache_key
  @available_codes ||= @translation_places.inject([]) { |all, i|
    all + i.available }.uniq.map { |i| i.code.downcase }
  (@locales_codes & @available_codes).join(',') + '@' +
    @filters.hash.to_s +
    R18n.default_loader.hash.to_s +
    @translation_places.hash.to_s +
    R18n.extension_places.hash.to_s
end