Module: RouteTranslator::Translator

Defined in:
lib/route_translator/translator.rb

Class Method Summary collapse

Class Method Details

.add_untranslated_helpers_to_controllers_and_views(old_name, helper_container) ⇒ Object

Add standard route helpers for default locale e.g.

I18n.locale = :de
people_path -> people_de_path
I18n.locale = :fr
people_path -> people_fr_path


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/route_translator/translator.rb', line 8

def self.add_untranslated_helpers_to_controllers_and_views(old_name, helper_container)
  ['path', 'url'].each do |suffix|
    new_helper_name = "#{old_name}_#{suffix}"

    helper_container.__send__(:define_method, new_helper_name) do |*args|
      locale_suffix = I18n.locale.to_s.underscore
      if respond_to?("#{old_name}_#{locale_suffix}_#{suffix}")
        __send__("#{old_name}_#{locale_suffix}_#{suffix}", *args)
      else
        __send__("#{old_name}_#{I18n.default_locale.to_s.underscore}_#{suffix}", *args)
      end
    end

    # Including the named routes helpers module
    [ActionController::TestCase, ActionView::TestCase, ActionMailer::TestCase].each do |klass|
      klass.__send__(:include, helper_container)
    end
  end
end

.default_locale?(locale) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/route_translator/translator.rb', line 78

def self.default_locale?(locale)
  I18n.default_locale.to_sym == locale.to_sym
end

.locale_param_present?(path) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/route_translator/translator.rb', line 101

def self.locale_param_present?(path)
  !(path.split('/').detect { |segment| segment.to_s == ":#{RouteTranslator.locale_param_key.to_s}" }.nil?)
end

.translate_name(n, locale) ⇒ Object



74
75
76
# File 'lib/route_translator/translator.rb', line 74

def self.translate_name(n, locale)
  "#{n}_#{locale.to_s.underscore}" if n.present?
end

.translate_path(path, locale) ⇒ Object

Translates a path and adds the locale prefix.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/route_translator/translator.rb', line 56

def self.translate_path(path, locale)
  new_path = path.dup
  final_optional_segments = new_path.slice!(/(\([^\/]+\))$/)
  translated_segments = new_path.split("/").map{ |seg| translate_path_segment(seg, locale) }.select{ |seg| !seg.blank? }

  # if not hiding locale then
  # add locale prefix if it's not the default locale,
  # or forcing locale to all routes,
  # or already generating actual unlocalized routes
  if !RouteTranslator.config.hide_locale && (!default_locale?(locale) || RouteTranslator.config.force_locale || RouteTranslator.config.generate_unlocalized_routes || RouteTranslator.config.generate_unnamed_unlocalized_routes)
    if !locale_param_present?(new_path)
      translated_segments.unshift locale.to_s.downcase
    end
  end

  "/#{translated_segments.join('/')}#{final_optional_segments}".gsub(/\/\(\//, '(/')
end

.translate_path_segment(segment, locale) ⇒ Object

Tries to translate a single path segment. If the path segment contains sth. like a optional format “people(.:format)”, only “people” will be translated, if there is no translation, the path segment is blank, begins with a “:” (param key) or “*” (wildcard), the segment is returned untouched



87
88
89
90
91
92
93
94
# File 'lib/route_translator/translator.rb', line 87

def self.translate_path_segment segment, locale
  return segment if segment.blank? or segment.starts_with?(":") or segment.starts_with?("(") or segment.starts_with?("*")

  appended_part = segment.slice!(/(\()$/)
  match = TRANSLATABLE_SEGMENT.match(segment)[1] rescue nil

  (translate_string(match, locale) || segment) + appended_part.to_s
end

.translate_string(str, locale) ⇒ Object



96
97
98
99
# File 'lib/route_translator/translator.rb', line 96

def self.translate_string(str, locale)
  res = I18n.translate(str, :scope => :routes, :locale => locale, :default => str)
  URI.escape(res)
end

.translations_for(app, conditions, requirements, defaults, route_name, anchor, route_set, &block) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/route_translator/translator.rb', line 28

def self.translations_for(app, conditions, requirements, defaults, route_name, anchor, route_set, &block)
  add_untranslated_helpers_to_controllers_and_views(route_name, route_set.named_routes.module)
  # Make sure the default locale is translated in last place to avoid
  # problems with wildcards when default locale is omitted in paths. The
  # default routes will catch all paths like wildcard if it is translated first
  available_locales = I18n.available_locales.dup
  available_locales.delete I18n.default_locale
  available_locales.push I18n.default_locale
  available_locales.each do |locale|
    new_conditions = conditions.dup
    new_conditions[:path_info] = translate_path(conditions[:path_info], locale)
    if new_conditions[:required_defaults] && !new_conditions[:required_defaults].include?(RouteTranslator.locale_param_key)
      new_conditions[:required_defaults] << RouteTranslator.locale_param_key if new_conditions[:required_defaults]
    end
    new_defaults = defaults.merge(RouteTranslator.locale_param_key => locale.to_s)
    new_requirements = requirements.merge(RouteTranslator.locale_param_key => locale.to_s)
    new_route_name = translate_name(route_name, locale)
    new_route_name = nil if new_route_name && route_set.named_routes.routes[new_route_name.to_sym] #TODO: Investigate this :(
    block.call(app, new_conditions, new_requirements, new_defaults, new_route_name, anchor)
  end
  if RouteTranslator.config.generate_unnamed_unlocalized_routes
    block.call(app, conditions, requirements, defaults, nil, anchor)
  elsif RouteTranslator.config.generate_unlocalized_routes
    block.call(app, conditions, requirements, defaults, route_name, anchor)
  end
end