Class: Rack::I18nRoutes::AliasMapping

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/i18n_routes/alias_mapping.rb

Overview

Describe translated paths as aliases for the normalized ones.

To be used as a mapping object for Rack::I18nRoutes.

If the list of aliases is not known at buildtime, you can use a AliasMappingUpdater.

Instance Method Summary collapse

Constructor Details

#initialize(aliases, opts = {}) ⇒ AliasMapping

Create a new alias-based Mapping object.

The aliases as stored in a hash. Each keys of the hash contain a normalized path; its value contains another hash that associates ids to one or more translations. The special id :children is used to specify the aliases of subpaths.

Examples:

A basic set of aliases


# "articles" is the normalized path; there are three available
# translations: an french translation ("articles") and two
# spanish translations ("artículos" and "articulos").

'articles' => {
  'fra' => 'articles',
  'spa' => ['artículos', 'articulos'],
}

A set of aliases with subpaths


# a special id `:children` is used to specify the aliases of
# subpaths

'articles' => {
  'fra' => 'articles',
  'spa' => ['artículos', 'articulos'],

  :children => {
    'the-victory' => {
      'fra' => 'la-victoire',
      'spa' => 'la-victoria',
    },
    'the-block' => {
      'fra' => 'le-bloc',
      'spa' => 'el-bloque',
    },
  },
}

An AliasMapping as mapping object in I18nRoutes


aliases = {
  'articles' => {
    'fra' => 'articles',
    'spa' => ['artículos', 'articulos'],

    :children => {
      'the-victory' => {
        'fra' => 'la-victoire',
        'spa' => 'la-victoria',
      },
      'the-block' => {
        'fra' => 'le-bloc',
        'spa' => 'el-bloque',
      },
    },
  },
}

MAPPING = Rack::I18nRoutes::AliasMapping.new(aliases)
use Rack::I18nRoutes, MAPPING

Parameters:

  • aliases (Hash)

    the aliases

  • opts (Hash) (defaults to: {})

    extra options for the mapping

Options Hash (opts):

  • :default (Foo)

    the language key associated with the normalized paths



83
84
85
86
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 83

def initialize(aliases, opts = {})
  @aliases = aliases
  @default_lang = opts[:default]
end

Instance Method Details

#map(path) ⇒ String

Returns:

  • (String)


90
91
92
93
94
95
96
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 90

def map(path)
  normalized_pieces, translated_pieces, found_langs = path_analysis(path)

  normalized_path = normalized_pieces.join('/')

  return normalized_path
end

#normalization_for(piece, aliases, replacement_language) ⇒ (String, Object)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • ((String, Object))


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
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 151

def normalization_for(piece, aliases, replacement_language)
  if aliases.nil?
    return nil, piece, @default_lang
  end

  entities = aliases.keys
  entities.each do |entity|
    if piece == entity
      translated_piece = piece_translation(piece, aliases[entity], replacement_language)
      return entity, translated_piece, @default_lang
    end

    subentities = aliases[entity].values.reject { |e| e.is_a? Hash }
    subentity = subentities.find { |s| Array(s).any? { |sube| piece == sube } }
    if !subentity.nil?
      lang = aliases[entity].index(subentity)
      translated_piece = piece_translation(piece, aliases[entity], replacement_language)
      return entity, translated_piece, lang
    end
  end

  # the piece is not present in the aliases

  return nil, piece, @default_lang
end

#path_analysis(path, replacement_language = :default) ⇒ (Array<String>, Array<String>, Array<Object>)

Returns:

  • ((Array<String>, Array<String>, Array<Object>))


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 108

def path_analysis(path, replacement_language = :default)
  orig_pieces = path.split('/')

  normalized_pieces = []
  translated_pieces = []
  found_langs = []

  # PATH_INFO always starts with / in Rack, so we directly move
  # the initial empty piece into the normalized ones

  pre_slash = orig_pieces.shift
  normalized_pieces << pre_slash
  translated_pieces << pre_slash

  aliases = @aliases

  orig_pieces.each do |orig_piece|
    normalized, translation, lang = normalization_for(orig_piece, aliases, replacement_language)
    replacement = (normalized || orig_piece)

    normalized_pieces << replacement
    translated_pieces << translation
    found_langs << lang

    if !aliases.nil? && aliases.has_key?(replacement)
      aliases = aliases[replacement][:children]
    else
      aliases = nil
    end
  end

  if path.end_with?('/')
    normalized_pieces << ""
    translated_pieces << ""
  end

  return normalized_pieces, translated_pieces, found_langs
end

#piece_translation(piece, aliases, replacement_language) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (String)


181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 181

def piece_translation(piece, aliases, replacement_language)
  if replacement_language == :default
    return piece
  end

  translated_pieces = Array(aliases[replacement_language])

  if translated_pieces.empty?
    return piece
  end

  return translated_pieces.first
end

#translate_into(path, language) ⇒ String

Returns:

  • (String)


100
101
102
103
104
# File 'lib/rack/i18n_routes/alias_mapping.rb', line 100

def translate_into(path, language)
  normalized_pieces, translated_pieces, found_langs = path_analysis(path, language)

  return translated_pieces.join('/')
end