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