Class: R18n::Locale

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

Overview

Information about locale (language, country and other special variant preferences). Locale was named by RFC 3066. For example, locale for French speaking people in Canada will be fr-CA.

Locale classes are placed in R18n::Locales module and storage install locales/ dir.

Each locale has sublocales – often known languages for people from this locale. For example, many Belorussians know Russian and English. If there is’t translation for Belorussian, it will be searched in Russian and next in English translations.

Usage

Get Russian locale and print it information

ru = R18n.locale('ru')
ru.title #=> "Русский"
ru.code  #=> "ru"
ru.ltr?  #=> true

Available data

  • code – locale RFC 3066 code;

  • title – locale name on it language;

  • ltr? – true on left-to-right writing direction, false for Arabic and Hebrew);

  • sublocales – often known languages for people from this locale;

  • week_start – does week start from :monday or :sunday.

You can see more available data about locale in samples in locales/ dir.

Constant Summary collapse

LOCALES_DIR =
File.join(__dir__, '..', '..', 'locales')
@@loaded =
{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.availableObject

Codes of all available locales.



62
63
64
65
66
# File 'lib/r18n-core/locale.rb', line 62

def self.available
  Dir.glob(File.join(LOCALES_DIR, '*.rb')).map do |i|
    File.basename(i, '.rb')
  end
end

.exists?(locale) ⇒ Boolean

Is locale has info file.

Returns:

  • (Boolean)


69
70
71
# File 'lib/r18n-core/locale.rb', line 69

def self.exists?(locale)
  File.exist?(File.join(LOCALES_DIR, "#{locale}.rb"))
end

.load(code) ⇒ Object

Load locale by RFC 3066 code.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/r18n-core/locale.rb', line 74

def self.load(code)
  original = code.to_s.gsub(/[^-_a-zA-Z]/, '')
  code = original.tr('_', '-').downcase

  @@loaded[code] ||= begin
    if exists? code
      require File.join(LOCALES_DIR, "#{code}.rb")
      name = code.gsub(/\w+/, &:capitalize).delete('-')
      R18n::Locales.const_get(name).new
    else
      UnsupportedLocale.new(original)
    end
  end
end

.set(properties) ⇒ Object

Set locale properties. Locale class will have methods for each propetry name, which return propetry value:

class R18n::Locales::En < R18n::Locale
  set title: 'English',
      code:  'en'
end

locale = R18n::Locales::En.new
locale.title #=> "English"
locale.code  #=> "en"


100
101
102
103
104
# File 'lib/r18n-core/locale.rb', line 100

def self.set(properties)
  properties.each_pair do |key, value|
    define_method(key) { value }
  end
end

Instance Method Details

#==(other) ⇒ Object

Is another locale has same code.



139
140
141
# File 'lib/r18n-core/locale.rb', line 139

def ==(other)
  self.class == other.class
end

#codeObject

Locale RFC 3066 code.



107
108
109
110
111
# File 'lib/r18n-core/locale.rb', line 107

def code
  name = self.class.name.split('::').last
  lang, culture = name.match(/([A-Z][a-z]+)([A-Z]\w+)?/).captures
  lang.downcase + (culture ? '-' + culture.upcase : '')
end

#format_date_full(date, year = true, *_params) ⇒ Object

Format date in most official form. For example, “December 31st, 2009”. For special cases you can replace it in locale’s class. If year is false date will be without year.



296
297
298
299
300
# File 'lib/r18n-core/locale.rb', line 296

def format_date_full(date, year = true, *_params)
  format = full_format
  format = year_format.sub('_', format) if year
  strftime(date, format)
end

#format_date_human(date, i18n, now = Date.today, *_params) ⇒ Object

Format date in human usable form. For example “5 days ago” or “yesterday”. In now you can set base time, which be used to get relative time. For special cases you can replace it in locale’s class.



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/r18n-core/locale.rb', line 270

def format_date_human(date, i18n, now = Date.today, *_params)
  days = (date - now).to_i
  case days
  when -6..-2
    i18n.human_time.days_ago(days.abs)
  when -1
    i18n.human_time.yesterday
  when 0
    i18n.human_time.today
  when 1
    i18n.human_time.tomorrow
  when 2..6
    i18n.human_time.after_days(days)
  else
    format_date_full(date, date.year != now.year)
  end
end

#format_date_standard(date, *_params) ⇒ Object

Format date in compact form. For example, “12/31/09”.



289
290
291
# File 'lib/r18n-core/locale.rb', line 289

def format_date_standard(date, *_params)
  strftime(date, date_format)
end

#format_float(float) ⇒ Object

Returns the float in String form, according to the rules of the locale. It will also put real typographic minus.



199
200
201
202
# File 'lib/r18n-core/locale.rb', line 199

def format_float(float)
  decimal = number_decimal
  format_integer(float.to_i) + decimal + float.to_s.split('.').last
end

#format_integer(integer) ⇒ Object

Returns the integer in String form, according to the rules of the locale. It will also put real typographic minus.



187
188
189
190
191
192
193
194
195
# File 'lib/r18n-core/locale.rb', line 187

def format_integer(integer)
  str = integer.to_s
  str[0] = '' if integer < 0 # Real typographic minus
  group = number_group

  str.gsub(/(\d)(?=(\d\d\d)+(?!\d))/) do |match|
    match + group
  end
end

#format_time(date, time) ⇒ Object

Format time and set date



230
231
232
# File 'lib/r18n-core/locale.rb', line 230

def format_time(date, time)
  strftime(time, time_format).sub('_', date.to_s)
end

#format_time_full(time, *_params) ⇒ Object

Format time in most official form. For example, “December 31st, 2009 12:59”. For special cases you can replace it in locale’s class.



263
264
265
# File 'lib/r18n-core/locale.rb', line 263

def format_time_full(time, *_params)
  format_time(format_date_full(time), time)
end

#format_time_human(time, i18n, now = Time.now, *_params) ⇒ Object

Format time in human usable form. For example “5 minutes ago” or “yesterday”. In now you can set base time, which be used to get relative time. For special cases you can replace it in locale’s class.



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/r18n-core/locale.rb', line 237

def format_time_human(time, i18n, now = Time.now, *_params)
  diff = time - now
  minutes = time.is_a?(DateTime) ? diff * 24 * 60.0 : diff / 60.0
  diff = minutes.abs
  if (diff > 24 * 60) || (time.mday != now.mday && diff > 12 * 24)
    format_time(format_date_human(time.to_date, i18n, now.to_date), time)
  elsif minutes > -1 && minutes < 1
    i18n.human_time.now
  elsif minutes >= 60
    i18n.human_time.after_hours((diff / 60.0).floor)
  elsif minutes <= -60
    i18n.human_time.hours_ago((diff / 60.0).floor)
  elsif minutes > 0
    i18n.human_time.after_minutes(minutes.round)
  else
    i18n.human_time.minutes_ago(minutes.round.abs)
  end
end

#format_time_standard(time, *_params) ⇒ Object

Format time in compact form. For example, “12/31/09 12:59”.



257
258
259
# File 'lib/r18n-core/locale.rb', line 257

def format_time_standard(time, *_params)
  format_time(format_date_standard(time), time)
end

#inspectObject

Human readable locale code and title.



149
150
151
# File 'lib/r18n-core/locale.rb', line 149

def inspect
  "Locale #{code} (#{title})"
end

#localize(obj, format = nil, *params) ⇒ Object

Convert object to String. It support Integer, 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.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/r18n-core/locale.rb', line 160

def localize(obj, format = nil, *params)
  case obj
  when Integer
    format_integer(obj)
  when Float, BigDecimal
    format_float(obj.to_f)
  when Time, DateTime, Date
    return strftime(obj, format) if format.is_a? String
    return month_standalone[obj.month - 1] if format == :month
    return obj.to_s if format == :human && !params.first.is_a?(I18n)

    type = obj.is_a?(Date) && !obj.is_a?(DateTime) ? 'date' : 'time'
    format ||= :standard
    format_method_name = "format_#{type}_#{format}"

    unless respond_to? format_method_name
      raise ArgumentError, "Unknown time formatter #{format}"
    end

    send format_method_name, obj, *params
  else
    obj.to_s
  end
end

#ltr?Boolean

Is locale has left-to-right write direction.

Returns:

  • (Boolean)


134
135
136
# File 'lib/r18n-core/locale.rb', line 134

def ltr?
  true
end

#month_abbrsObject



125
126
127
# File 'lib/r18n-core/locale.rb', line 125

def month_abbrs
  month_names
end

#month_standaloneObject



121
122
123
# File 'lib/r18n-core/locale.rb', line 121

def month_standalone
  month_names
end

#pluralize(n) ⇒ Object

Return pluralization type for n items. This is simple form. For special cases you can replace it in locale’s class.



304
305
306
307
308
309
310
311
312
313
# File 'lib/r18n-core/locale.rb', line 304

def pluralize(n)
  case n
  when 0
    0
  when 1
    1
  else
    'n'
  end
end

#strftime(time, format) ⇒ Object

Same that Time.strftime, but translate months and week days names. In time you can use Time, DateTime or Date object. In format you can use standard strftime format.



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/r18n-core/locale.rb', line 207

def strftime(time, format)
  translated = ''
  format.scan(/%[EO]?.|./o) do |c|
    translated +=
      case c.sub(/^%[EO]?(.)$/o, '%\\1')
      when '%A'
        wday_names[time.wday]
      when '%a'
        wday_abbrs[time.wday]
      when '%B'
        month_names[time.month - 1]
      when '%b'
        month_abbrs[time.month - 1]
      when '%p'
        time.hour < 12 ? time_am : time_pm
      else
        c
      end
  end
  time.strftime(translated)
end

#supported?Boolean

Is locale has information file. In this class always return true.

Returns:

  • (Boolean)


144
145
146
# File 'lib/r18n-core/locale.rb', line 144

def supported?
  true
end

#wday_abbrsObject



129
130
131
# File 'lib/r18n-core/locale.rb', line 129

def wday_abbrs
  wday_names
end