Module: RouteTranslator::RouteSet::Translator

Included in:
RouteTranslator::RouteSet
Defined in:
lib/route_translator/route_set/translator.rb

Instance Method Summary collapse

Instance Method Details

#add_untranslated_helpers_to_controllers_and_views(old_name) ⇒ 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


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

def add_untranslated_helpers_to_controllers_and_views old_name
  ['path', 'url'].map do |suffix|
    new_helper_name = "#{old_name}_#{suffix}"

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

    new_helper_name.to_sym
  end
end

#request_method_array(reg) ⇒ Object



112
113
114
# File 'lib/route_translator/route_set/translator.rb', line 112

def request_method_array(reg)
  reg.source.gsub(%r{\^|\$}, "").split("|")
end

#translateObject

Translate a specific RouteSet, usually Rails.application.routes, but can be a RouteSet of a gem, plugin/engine etc.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/route_translator/route_set/translator.rb', line 6

def translate
  Rails.logger.info "Translating routes (default locale: #{default_locale})" if defined?(Rails) && defined?(Rails.logger)

  # save original routes and clear route set
  original_routes = routes.dup
  original_named_routes = named_routes.routes.dup  # Hash {:name => :route}

  # The filter method exists if the "routing-filter" gem is used
  original_filters = set.respond_to?(:filters) ? set.filters.dup : []

  routes_to_create = []
  original_routes.each do |original_route|
    if localized_routes && localized_routes.include?(original_route.to_s)
      translations_for(original_route).each do |translated_route_args|
        routes_to_create << translated_route_args
      end
    else
      route = untranslated_route original_route
      routes_to_create << route
    end
    # Always generate unlocalized routes?
    if RouteTranslator.config.generate_unlocalized_routes
      route = untranslated_route original_route
      routes_to_create << route
    end
  end

  reset!

  routes_to_create.each do |r|
    add_route(*r)
  end

  if original_filters.any?
    set.filters << original_filters
    set.filters.flatten!
  end

  Hash[original_named_routes.select{|k,v| localized_routes && localized_routes.include?(v.to_s)}].each_key do |route_name|
    named_routes.helpers.concat add_untranslated_helpers_to_controllers_and_views(route_name)
  end

  finalize!
  named_routes.install
end

#translate_path(path, locale) ⇒ Object

Translates a path and adds the locale prefix.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/route_translator/route_set/translator.rb', line 117

def translate_path(path, locale)
  final_optional_segments = path.slice!(/(\(.+\))$/)
  new_path = path.split("/").map{|seg| translate_path_segment(seg, locale)}.join('/')

  # Add locale prefix if it's not the default locale,
  # or forcing locale to all routes,
  # or already generating actual unlocalized routes
  if !default_locale?(locale) ||
    RouteTranslator.config.force_locale ||
    RouteTranslator.config.generate_unlocalized_routes
    new_path = "/#{locale.downcase}#{new_path}"
  end

  new_path = "/" if new_path.blank?
  "#{new_path}#{final_optional_segments}"
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 or begins with a “:” (param key), the segment is returned untouched



139
140
141
142
143
144
145
# File 'lib/route_translator/route_set/translator.rb', line 139

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

  match = TRANSLATABLE_SEGMENT.match(segment)[1] rescue nil

  (translate_string(match, locale) || segment)
end

#translate_route(route, locale) ⇒ Object

Generate translation for a single route for one locale



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/route_translator/route_set/translator.rb', line 83

def translate_route route, locale
  path_regex = route.path.respond_to?(:spec) ? route.path.spec : route.path

  conditions = route.conditions.dup.merge({
    :path_info => translate_path(path_regex.dup.to_s, locale)
  })

  conditions[:request_method] = request_method_array(conditions[:request_method]) if conditions[:request_method]

  requirements = route.requirements.dup.merge!(LOCALE_PARAM_KEY => locale)
  defaults = route.defaults.dup.merge LOCALE_PARAM_KEY => locale

  new_name = "#{route.name}_#{locale_suffix(locale)}" if route.name

  [route.app, conditions, requirements, defaults, new_name]
end

#translate_string(str, locale) ⇒ Object



147
148
149
# File 'lib/route_translator/route_set/translator.rb', line 147

def translate_string(str, locale)
  @dictionary[locale.to_s][str.to_s]
end

#translations_for(route) ⇒ Object

Generate translations for a single route for all available locales



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

def translations_for route
  available_locales.map do |locale|
    translate_route(route, locale.dup) #we duplicate the locale string to ensure it's not frozen
  end
end

#untranslated_route(route) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/route_translator/route_set/translator.rb', line 100

def untranslated_route route
  path_regex = route.path.respond_to?(:spec) ? route.path.spec : route.path

  conditions = route.conditions.dup.merge({
    :path_info => path_regex.to_s
  })

  conditions[:request_method] = request_method_array(conditions[:request_method]) if conditions[:request_method]

  [route.app, conditions, route.requirements.dup, route.defaults.dup, route.name]
end