Class: Rack::LocaleChooser::Chooser

Inherits:
Object
  • Object
show all
Defined in:
lib/rack-locale_chooser/chooser.rb

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Chooser.



5
6
7
8
9
10
11
12
13
# File 'lib/rack-locale_chooser/chooser.rb', line 5

def initialize(app, options = {})
  @app, @options = app, {
    :default_domain => 'example.com',
    :geodb_path => '/usr/local/Cellar/geoip/1.4.6/share/GeoIP/GeoLiteCity.dat',
    :host_mappings => {}
  }.merge(options)
  @geodb = Net::GeoIP.new(@options[:geodb_path]) 
  @logger = options[:logger]
end

Instance Method Details

#browser_localeObject



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rack-locale_chooser/chooser.rb', line 71

def browser_locale
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
  if lang = @env['HTTP_ACCEPT_LANGUAGE']
    lang = lang.split(",").map { |l|
      l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
      l.split(';q=')
    }.first
    browser_locale = lang.first.split("-").first
  else
    browser_locale = I18n.default_locale
  end
  @options[:host_mappings].has_key?(browser_locale.to_sym) ? browser_locale : I18n.default_locale      
end

#call(env) ⇒ Object



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
# File 'lib/rack-locale_chooser/chooser.rb', line 15

def call(env)
  @env = env

  @request = Rack::Request.new(@env)
  
  @original_url = @request.url
  
  set_session_options
  
  set_locale
  
  @logger.debug("Request URL: #{@original_url} | Localized URL: #{localized_url} | URL Locale: #{url_locale} | Cookie Locale: #{cookie_locale} | Geo Locale: #{geo_locale} | Browser Locale: #{browser_locale} | Definitive Locale: #{locale} | City: #{@env['rack.city']}") if @logger
  
  if @request.post? || @request.put? || @request.delete? then        
    @app.call(@env)
  else             
    if @original_url != localized_url then 
      [301, {'Location' => localized_url}, '']
    else
      status, headers, body = @app.call(@env)
      response = Rack::Response.new(body, status, headers)
      response.set_cookie('locale', {
        :value => I18n.locale,
        :path => '/',
        :domain => @env["rack.session.options"][:domain]})
      response.finish
    end  
  end
end


63
64
65
# File 'lib/rack-locale_chooser/chooser.rb', line 63

def cookie_locale
  @request.cookies['locale'] unless @options[:disable_cookie]
end

#geo_localeObject



67
68
69
# File 'lib/rack-locale_chooser/chooser.rb', line 67

def geo_locale
  @options[:country_mappings][geo_record.country_code] if @options[:country_mappings] and geo_record
end

#geo_recordObject



50
51
52
53
54
55
56
# File 'lib/rack-locale_chooser/chooser.rb', line 50

def geo_record
  @geo_record = begin
      @geodb[@env["REMOTE_ADDR"]]
    rescue Net::GeoIP::RecordNotFoundError
      return nil
    end
end

#localeObject



85
86
87
# File 'lib/rack-locale_chooser/chooser.rb', line 85

def locale
  url_locale || cookie_locale || geo_locale || browser_locale
end

#localized_urlObject



99
100
101
102
103
# File 'lib/rack-locale_chooser/chooser.rb', line 99

def localized_url
  current_host = @request.host.gsub(/http:\/\//, '')
  return @request.url.gsub(current_host, @options[:host_mappings][locale.to_sym]) if @options[:host_mappings][locale.to_sym]
  @original_url    
end

#set_localeObject



89
90
91
92
93
94
95
96
97
# File 'lib/rack-locale_chooser/chooser.rb', line 89

def set_locale
  I18n.locale = @env['rack.locale'] = locale.to_sym
  begin
    @env['rack.city'] = geo_record.city
    @env['rack.country_code'] = geo_record.country_code
  rescue
    return nil
  end
end

#set_session_optionsObject



45
46
47
48
# File 'lib/rack-locale_chooser/chooser.rb', line 45

def set_session_options
  @env['rack.session.options'] = {} unless @env['rack.session.options']
  @env['rack.session.options'][:domain] = @options[:default_domain]
end

#url_localeObject



58
59
60
61
# File 'lib/rack-locale_chooser/chooser.rb', line 58

def url_locale 
  hosts = @options[:host_mappings].invert
  hosts[@request.host] if hosts.has_key?(@request.host)
end