Class: Rack::I18nLocaleSwitcher

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/i18n_locale_switcher.rb

Constant Summary collapse

LOCALE_PATTERN =
'([a-zA-Z]{2,3})(-[a-zA-Z]{2,3})?'.freeze
SOURCES =
[ :param, :path, :host, :header ].freeze
REDIRECTS =
[ :param, :path, :host ].freeze
DEFAULT_OPTIONS =
{
  :param     => 'locale',
  :source    => SOURCES,
  :redirect  => nil,
  :canonical => false,
  :except    => nil
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ I18nLocaleSwitcher

Returns a new instance of I18nLocaleSwitcher.



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
# File 'lib/rack/i18n_locale_switcher.rb', line 19

def initialize(app, options = {})
  @app = app
  
  invalid_options = (options.keys - DEFAULT_OPTIONS.keys)
  
  if invalid_options.any?
    raise ArgumentError, "Invalid option(s) #{ invalid_options.map(&:inspect).join(', ') }" 
  end
  
  options = DEFAULT_OPTIONS.merge(options)

  @param     = options[:param]
  @canonical = options[:canonical]
  @except    = options[:except]

  @sources = options[:source]      
  @sources = Array(@sources) unless @sources.is_a?(Array)
  
  invalid_sources = @sources - SOURCES

  if invalid_sources.any?
    raise ArgumentError, "Invalid source(s) #{ invalid_sources.map(&:inspect).join(', ') }" 
  end

  @redirect = options[:redirect]

  unless @redirect.nil? || REDIRECTS.include?(@redirect)
    raise ArgumentError, "Invalid redirect option #{ @redirect.inspect }" 
  end
end

Instance Method Details

#call(env) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rack/i18n_locale_switcher.rb', line 50

def call(env)
  return @app.call(env) if env['PATH_INFO'] =~ @except
  
  I18n.locale = I18n.default_locale

  env['PATH_INFO'].gsub!(/([^\/])\/$/, '\1')

  request = Rack::Request.new(env)
  request_url = request.url

  source = nil
  @sources.each do |src|
    locale = send(:"extract_locale_from_#{src}", env)
    if locale && source.nil?
      source = src
      I18n.locale = locale
    end
  end

  if @redirect
    unless @canonical && I18n.locale == I18n.default_locale
      send(:"set_locale_in_#@redirect", env)
    end
  
    if request.url != request_url
      env['PATH_INFO'] = '' if env['PATH_INFO'] == '/'
      return [ 301, { 'Location' => request.url }, ["Redirecting"]]
    end
  end
  
  @app.call(env)
end