Module: Mova::Scope

Extended by:
Scope
Included in:
Scope
Defined in:
lib/mova/scope.rb

Overview

Note:

In YAML (and other storages that map to a hash) you can’t store a value for a nesting level itself.

errors: !can't have translation here
  blank: Please enter a value

Other key-value storages usually don’t have such limitation, however, it’s better to not introduce incompatibles in this area.

Translation keys are usually organized in a tree, where each nesting level corresponds to a specific part of your application. Such hierarchical organization allows to reuse the keys and keep their names relatively short.

Full path to a key forms a scope. Think of a scope as a namespace.

# here we have an example YAML file with "blank" keys within different scopes
activemodel:
  errors:
    blank: Can't be blank
    message:
      blank: Please provide a message

Since Mova is designed to work with any key-value storage, we need to store a key with its own full scope and a locale. We use dot-separated strings as it’s a common format in Ruby community.

"en.activemodel.errors.blank"
"en.activemodel.errors.message.blank"

Since:

  • 0.1.0

Constant Summary collapse

SEPARATOR =

Since:

  • 0.1.0

".".freeze

Instance Method Summary collapse

Instance Method Details

#cross_join(locales, keys) ⇒ Array<String>

Combines each locale with all keys.

Examples:

Scope.cross_join([:de, :en], [:hello, :hi]) #=>
  ["de.hello", "de.hi", "en.hello", "en.hi"]

Since:

  • 0.1.0



88
89
90
91
92
# File 'lib/mova/scope.rb', line 88

def cross_join(locales, keys)
  locales.map do |locale|
    keys.map { |key| join(locale, key) }
  end.flatten
end

#flatten(translations, current_scope = nil) ⇒ Hash{String => String}

Recurrently flattens hash by converting its keys to fully scoped ones.

Examples:

Scope.flatten(en: {common: {hello: "hi"}}, de: {hello: "Hallo"}) #=>
  {"en.common.hello" => "hi", "de.hello" => "Hallo"}

Since:

  • 0.1.0



68
69
70
71
72
73
74
75
76
77
# File 'lib/mova/scope.rb', line 68

def flatten(translations, current_scope = nil)
  translations.each_with_object({}) do |(key, value), memo|
    scope = current_scope ? join(current_scope, key) : key.to_s
    if value.is_a?(Hash)
      memo.merge!(flatten(value, scope))
    else
      memo[scope] = value
    end
  end
end

#join(*parts) ⇒ String

Makes a new scope from given parts.

Examples:

Scope.join("hello", "world") #=> "hello.world"
Scope.join([:hello, "world"]) #=> "hello.world"

Since:

  • 0.1.0



43
44
45
# File 'lib/mova/scope.rb', line 43

def join(*parts)
  parts.join(SEPARATOR)
end

#split(scope) ⇒ Array<String>

Split a scope into parts.

Examples:

Scope.split("hello.world") #=> ["hello", "world"]

Since:

  • 0.1.0



54
55
56
# File 'lib/mova/scope.rb', line 54

def split(scope)
  scope.split(SEPARATOR)
end