module RailsTranslateRoutes::Translator

Public Instance Methods

add_prefix?(locale) click to toggle source

Add prefix for all non-default locales

# File lib/rails-translate-routes.rb, line 320
def add_prefix? locale
  if @no_prefixes
    false
  elsif !default_locale?(locale) || @prefix_on_default_locale
    true
  else
    false
  end
end
add_root_route(root_route, route_set) click to toggle source

Add unmodified root route to route_set

# File lib/rails-translate-routes.rb, line 233
def add_root_route root_route, route_set
  if @prefix_on_default_locale
    if Rails.version >= '3.2'
      conditions = { :path_info => root_route.path.spec.to_s }
      conditions[:request_method] = parse_request_methods root_route.verb if root_route.verb != //
      route_set.add_route root_route.app, conditions, root_route.requirements, root_route.defaults, root_route.name
    else
      root_route.conditions[:path_info] = root_route.conditions[:path_info].dup
      route_set.set.add_route *root_route
      route_set.named_routes[root_route.name] = root_route
      route_set.routes << root_route
    end
  end
end
add_untranslated_helpers_to_controllers_and_views(old_name) click to toggle source

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
# File lib/rails-translate-routes.rb, line 253
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|
        send "#{old_name}_#{locale_suffix(I18n.locale)}_#{suffix}", *args
      end
    end

    new_helper_name.to_sym
  end
end
translate(route_set) click to toggle source

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

# File lib/rails-translate-routes.rb, line 185
def translate route_set
  Rails.logger.info "Translating routes (default locale: #{default_locale})" if defined?(Rails) && defined?(Rails.logger)

  # save original routes and clear route set
  original_routes = route_set.routes.dup                     # Array [routeA, routeB, ...]

  if Rails.version >= '3.2'
    original_routes.routes.delete_if{|r| r.path.spec.to_s == '/assets'  }
  else
    original_routes.delete_if{|r| r.path == '/assets'}
  end

  original_named_routes = route_set.named_routes.routes.dup  # Hash {:name => :route}

  if Rails.version >= '3.2'
    translated_routes = []
    original_routes.each do |original_route|
      translations_for(original_route).each do |translated_route_args|
        translated_routes << translated_route_args
      end
    end

    reset_route_set route_set

    translated_routes.each do |translated_route_args|
      route_set.add_route *translated_route_args
    end
  else
    reset_route_set route_set

    original_routes.each do |original_route|
      translations_for(original_route).each do |translated_route_args|
        route_set.add_route *translated_route_args
      end
    end
  end

  original_named_routes.each_key do |route_name|
    route_set.named_routes.helpers.concat add_untranslated_helpers_to_controllers_and_views(route_name)
  end

  if root_route = original_named_routes[:root]
    add_root_route root_route, route_set
  end

end
translate_path(path, locale) click to toggle source

Translates a path and adds the locale prefix.

# File lib/rails-translate-routes.rb, line 331
def translate_path path, locale
  final_optional_segments = path.match(/(\(.+\))$/)[1] rescue nil   # i.e: (.:format)
  path_without_optional_segments = final_optional_segments ? path.gsub(final_optional_segments,'') : path
  path_segments = path_without_optional_segments.split("/")
  new_path = path_segments.map{ |seg| translate_path_segment(seg, locale) }.join('/')
  new_path = "/#{locale}#{new_path}" if add_prefix?(locale)
  new_path = '/' if new_path.blank?
  final_optional_segments ? new_path + final_optional_segments : new_path
end
translate_path_segment(segment, locale) click to toggle source

Tries to translate a single path segment. If the path segment contains sth. like an 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

# File lib/rails-translate-routes.rb, line 346
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) click to toggle source

Generate translation for a single route for one locale

# File lib/rails-translate-routes.rb, line 280
def translate_route route, locale
  if Rails.version >= '3.2'
    conditions = { :path_info => translate_path(route.path.spec.to_s, locale) }
    conditions[:request_method] = parse_request_methods route.verb if route.verb != //
    if route.constraints
      route.constraints.each do |k,v|
        conditions[k] = v unless k == :request_method
      end
    end
    defaults = route.defaults.merge LOCALE_PARAM_KEY => locale.dup
  else
    conditions = { :path_info => translate_path(route.path, locale) }
    conditions[:request_method] = parse_request_methods route.conditions[:request_method] if route.conditions.has_key? :request_method
    defaults = route.defaults.merge LOCALE_PARAM_KEY => locale
  end

  requirements = route.requirements.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) click to toggle source
# File lib/rails-translate-routes.rb, line 354
def translate_string str, locale
  @dictionary[locale.to_s][str.to_s]
end
translations_for(route) click to toggle source

Generate translations for a single route for all available locales

# File lib/rails-translate-routes.rb, line 268
def translations_for route
  translated_routes = []
  available_locales.map do |locale|
    translated_routes << translate_route(route, locale)
  end

  # add untranslated_route without url helper if we want to keep untranslated routes
  translated_routes << untranslated_route(route) if @keep_untranslated_routes
  translated_routes
end
untranslated_route(route) click to toggle source

Re-generate untranslated routes (original routes) with name set to nil (which prevents conflict with default untranslated_urls)

# File lib/rails-translate-routes.rb, line 303
def untranslated_route route
  conditions = {}
  if Rails.version >= '3.2'
    conditions[:path_info] = route.path.spec.to_s
    conditions[:request_method] = parse_request_methods route.verb if route.verb != //
    conditions[:subdomain] = route.constraints[:subdomain] if route.constraints
  else
    conditions[:path_info] = route.path
    conditions[:request_method] = parse_request_methods route.conditions[:request_method] if route.conditions.has_key? :request_method
  end
  requirements = route.requirements
  defaults = route.defaults

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

Private Instance Methods

parse_request_methods(methods_regexp) click to toggle source

expects methods regexp to be in a format: /^GET$/ or /^GET|POST$/ and returns array [“GET”, “POST”]

# File lib/rails-translate-routes.rb, line 371
def parse_request_methods methods_regexp
  methods_regexp.source.gsub(/\^([a-zA-Z\|]+)\$/, "\\1").split("|")
end
remove_all_methods_in(mod) click to toggle source
# File lib/rails-translate-routes.rb, line 364
def remove_all_methods_in mod
  mod.instance_methods.each do |method|
    mod.send :remove_method, method
  end
end
reset_route_set(route_set) click to toggle source
# File lib/rails-translate-routes.rb, line 359
def reset_route_set route_set
  route_set.clear!
  remove_all_methods_in route_set.named_routes.module
end