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.



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

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.



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

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”.



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

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.



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

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.



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

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



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

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.



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

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.



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

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”.



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

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
# 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

    unless %i[human full standard].include? format
      raise ArgumentError, "Unknown time formatter #{format}"
    end

    send "format_#{type}_#{format}", 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.



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

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.



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

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