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
}.freeze

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of I18nLocaleSwitcher.



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

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]

  @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



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

def call(env)
  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