module RailsTranslateRoutes::Translator
Public Instance Methods
Add prefix for all non-default locales
# File lib/rails-translate-routes.rb, line 345 def add_prefix? locale if @no_prefixes false elsif !default_locale?(locale) || @prefix_on_default_locale true else false end end
Add unmodified root route to route_set
# File lib/rails-translate-routes.rb, line 242 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 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 262 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(args.select{|arg| arg.is_a?(Hash)}.first.try(:[], :locale) || I18n.locale)}_#{suffix}", *args end # !!! very dirty hack to ensure it works inside Engines # # helper_container.send :define_method, :method_missing do |*args| # metod = args.shift # if metod[/_path/] || metod[/_url/] and self.class != helper_container and !metod[/\w{2}(_path|_url)/] # self.class.send :define_method, metod do |*arguments| # locale = arguments.select{|arg| arg.is_a?(Hash)}.first.try(:[], :locale) # send metod.to_s.gsub(/path$/, "#{locale || I18n.locale}_path").gsub(/url$/, "#{locale || I18n.locale}_url"), *arguments # end # send *args.unshift(metod) # else # super *args.unshift(metod) # end # end end new_helper_name.to_sym end end
# File lib/rails-translate-routes.rb, line 364 def split_translate_join(segment, locale, separators, translate = true) separator = separators[0] final_optional_segments = segment[Regexp.new("(#{'\\' + separator })$")] || "" segment.split(separator).map do |s| if separators[1..-1].any? split_translate_join(s, locale, separators[1..-1], translate) else translate ? translate_path_segment(s,locale) : s end end.join(separator) + (final_optional_segments != "/" ? final_optional_segments : '') end
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 193 def translate route_set route_set ||= custom_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
Translates a path and adds the locale prefix.
# File lib/rails-translate-routes.rb, line 356 def translate_path path, locale new_path = split_translate_join path, locale, [')','(','/'], false new_path = split_translate_join path, locale, [')','(','/'] new_path = "/:locale#{new_path || '/'}" if add_prefix?(locale) new_path = '/' if new_path.blank? new_path end
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 381 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
Generate translation for a single route for one locale
# File lib/rails-translate-routes.rb, line 304 def translate_route route, locale locale = locale.to_s 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
# File lib/rails-translate-routes.rb, line 389 def translate_string str, locale @dictionary[locale.to_s][str.to_s] end
Generate translations for a single route for all available locales
# File lib/rails-translate-routes.rb, line 292 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
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 328 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
expects methods regexp to be in a format: /^GET$/ or /^GET|POST$/ and returns array [“GET”, “POST”]
# File lib/rails-translate-routes.rb, line 406 def parse_request_methods methods_regexp methods_regexp.source.gsub(/\^([a-zA-Z\|]+)\$/, "\\1").split("|") end
# File lib/rails-translate-routes.rb, line 399 def remove_all_methods_in mod mod.instance_methods.each do |method| mod.send :remove_method, method end end
# File lib/rails-translate-routes.rb, line 394 def reset_route_set route_set route_set.clear! remove_all_methods_in route_set.named_routes.module end