Class: Tater

Inherits:
Object
  • Object
show all
Defined in:
lib/tater.rb,
lib/tater/hash.rb,
lib/tater/utils.rb,
lib/tater/aliases.rb,
lib/tater/version.rb

Overview

:nodoc:

Defined Under Namespace

Modules: HashExcept, Utils Classes: MissingLocalizationFormat, UnLocalizableObject

Constant Summary collapse

DEFAULT =
'default'
DELIMITING_REGEX =
/(\d)(?=(\d\d\d)+(?!\d))/.freeze
HASH =
{}.freeze
SEPARATOR =
'.'
SUBSTITUTION_REGEX =
/%(|\^)[aAbBpP]/.freeze
VERSION =
'3.0.6'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cascade: false, locale: nil, messages: nil, path: nil) ⇒ Tater

Returns a new instance of Tater.

Parameters:

  • cascade (Boolean) (defaults to: false)

    A boolean indicating if lookups should cascade by default.

  • locale (String) (defaults to: nil)

    The default locale.

  • messages (Hash) (defaults to: nil)

    A hash of messages ready to be loaded in.

  • path (String) (defaults to: nil)

    A path to search for YAML or Ruby files to load messages from.



45
46
47
48
49
50
51
52
53
54
# File 'lib/tater.rb', line 45

def initialize(cascade: false, locale: nil, messages: nil, path: nil)
  @available = []
  @cache = {}
  @cascade = cascade
  @locale = locale
  @messages = {}

  load(path: path) if path
  load(messages: messages) if messages
end

Instance Attribute Details

#availableArray<String> (readonly)

An array of the available locale codes found in loaded messages.

Returns:

  • (Array<String>)


29
30
31
# File 'lib/tater.rb', line 29

def available
  @available
end

#localeString

Returns:

  • (String)


32
33
34
# File 'lib/tater.rb', line 32

def locale
  @locale
end

#messagesHash (readonly)

Returns:

  • (Hash)


35
36
37
# File 'lib/tater.rb', line 35

def messages
  @messages
end

Instance Method Details

#available?(locale) ⇒ Boolean

Is this locale available in our current set of messages?

Returns:

  • (Boolean)


71
72
73
# File 'lib/tater.rb', line 71

def available?(locale)
  available.include?(locale.to_s)
end

#cascades?Boolean

Do lookups cascade by default?

Returns:

  • (Boolean)


64
65
66
# File 'lib/tater.rb', line 64

def cascades?
  @cascade
end

#includes?(key, options = HASH) ⇒ Boolean

Check that there’s a key at the given path.

Parameters:

  • key (String)

    The period-separated key path to look within our messages for.

  • options (Hash) (defaults to: HASH)

    Options to pass to the #lookup method, including locale overrides.

Options Hash (options):

  • :cascade (Boolean)

    Should this lookup cascade or not? Can override @cascade.

  • :locale (String)

    A specific locale to lookup within. This will take precedence over the :locales option.

  • :locales (Array<String>)

    An array of locales to look within.

Returns:

  • (Boolean)


219
220
221
222
223
# File 'lib/tater.rb', line 219

def includes?(key, options = HASH)
  return !lookup(key).nil? if options.empty?

  !lookup_with_options(key, options).nil?
end

#inspectString

Returns:

  • (String)


57
58
59
# File 'lib/tater.rb', line 57

def inspect
  %(#<Tater:#{ object_id } @cascade=#{ @cascade } @locale="#{ @locale }" @available=#{ @available }>)
end

#load(path: nil, messages: nil) ⇒ Object

Load messages into our internal cache, either from a path containing YAML files or a Hash of messages.

Parameters:

  • path (String) (defaults to: nil)

    A path to search for YAML or Ruby files to load messages from.

  • messages (Hash) (defaults to: nil)

    A hash of messages ready to be loaded in.



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
# File 'lib/tater.rb', line 82

def load(path: nil, messages: nil)
  return if path.nil? && messages.nil?

  if path
    Dir.glob(File.join(path, '**', '*.{yml,yaml}')).each do |file|
      @messages = Utils.deep_merge(@messages, YAML.load_file(file))
    end

    Dir.glob(File.join(path, '**', '*.rb')).each do |file|
      @messages = Utils.deep_merge(@messages, Utils.deep_stringify_keys(eval(File.read(file), binding, file))) # rubocop:disable Security/Eval
    end
  end

  @messages = Utils.deep_merge(@messages, Utils.deep_stringify_keys(messages)) if messages
  @messages = Utils.deep_freeze(@messages)

  # Update our available locales.
  @available.replace(@messages.keys.map(&:to_s).sort)

  # Not only does this clear our cache but it establishes the basic structure
  # that we rely on in other methods.
  @cache.clear

  @messages.each_key do |key|
    @cache[key] = { false => {}, true => {} }
  end
end

#localize(object, options = HASH) ⇒ String Also known as: l

Localize an Array, Date, Time, DateTime, or Numeric object.

Parameters:

  • object (Array<String>, Date, Time, DateTime, Numeric)

    The object to localize.

  • options (Hash) (defaults to: HASH)

    Options to configure localization.

Options Hash (options):

  • :format (String)

    The key or format string to use for localizing the current object.

  • :locale (String)

    The locale to use in lieu of the current default.

  • :delimiter (String)

    The delimiter to use when localizing numeric values.

  • :separator (String)

    The separator to use when localizing numeric values.

  • :two_words_connector (String)

    The string used to join two array elements together e.g. “ and ”.

  • :words_connector (String)

    The string used to connect multiple array elements e.g. “, ”.

  • :last_word_connector (String)

    The string used to connect the final element with preceding array elements e.g. “, and ”.

Returns:

  • (String)

    A localized version of the object passed in.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/tater.rb', line 144

def localize(object, options = HASH)
  case object
  when String
    object
  when Numeric
    localize_numeric(object, options)
  when Date, Time, DateTime
    localize_datetime(object, options)
  when Array
    localize_array(object, options)
  else
    raise(UnLocalizableObject, "The object class #{ object.class } cannot be localized by Tater.")
  end
end

#lookup(key, locale: nil, cascade: nil) ⇒ Object

Lookup a key in the messages hash, using the current locale or an override.

Examples:

Using the default locale, look up a key’s value.

i18n = Tater.new(locale: 'en', messages: { 'en' => { 'greeting' => { 'world' => 'Hello, world!' } } })
i18n.lookup('greeting.world') # => "Hello, world!"

Parameters:

  • key (String)

    The period-separated key path to look for within our messages.

  • locale (String) (defaults to: nil)

    A locale to use instead of our current one, if any.

  • cascade (Boolean) (defaults to: nil)

    A boolean to forcibly set the cascade option for this lookup.

Returns:

  • Basically anything that can be stored in your messages Hash.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/tater.rb', line 174

def lookup(key, locale: nil, cascade: nil)
  locale =
    if locale.nil?
      @locale
    else
      locale.to_s
    end

  cascade = @cascade if cascade.nil?

  @cache[locale][cascade][key] ||= begin
    path = key.split(SEPARATOR)

    message = @messages[locale].dig(*path)

    if message.nil? && cascade
      message =
        while path.length > 1
          path.delete_at(path.length - 2)
          attempt = @messages[locale].dig(*path)

          break attempt unless attempt.nil?
        end
    end

    message
  end
end

#translate(key, options = HASH) ⇒ String Also known as: t

Translate a key path and optional interpolation arguments into a string. It’s effectively a combination of #lookup and #interpolate.

Examples:

Tater.new(locale: 'en', messages: { 'en' => { 'hi' => 'Hello' }}).translate('hi') # => 'Hello'

Parameters:

  • key (String)

    The period-separated key path to look within our messages for.

  • options (Hash) (defaults to: HASH)

    Options, including values to interpolate to any found string.

Options Hash (options):

  • :cascade (Boolean)

    Should this lookup cascade or not? Can override @cascade.

  • :default (String)

    A default string to return, should lookup fail.

  • :locale (String)

    A specific locale to lookup within.

  • :locales (Array<String>)

    An array of locales to look within. This will take precedence over the :locale option and will append the default :locale option passed during initialization if present.

Returns:

  • (String)

    The translated and interpreted string, if found, or any data at the defined key.



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/tater.rb', line 250

def translate(key, options = HASH)
  if options.empty?
    case (message = lookup(key))
    when String
      message
    when Proc
      message.call(key)
    else
      "Tater lookup failed: #{ locale }.#{ key }"
    end
  else
    case (message = lookup_with_options(key, options))
    when String
      return message unless Utils.interpolation_string?(message)

      Utils.interpolate!(message, options.except(:cascade, :default, :locale, :locales))
    when Proc
      message.call(key, options.except(:cascade, :default, :locale, :locales))
    else
      options[:default] || "Tater lookup failed: #{ options[:locale] || options[:locales] || locale }.#{ key }"
    end
  end
end