Class: Utopia::Middleware::Localization

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/middleware/localization.rb,
lib/utopia/middleware/localization/name.rb

Defined Under Namespace

Modules: Name

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Localization.



28
29
30
31
32
33
34
35
# File 'lib/utopia/middleware/localization.rb', line 28

def initialize(app, options = {})
	@app = app

	@default_locale = options[:default] || "en"
	@all_locales = options[:all] || ["en"]
	
	@nonlocalized = options[:nonlocalized] || []
end

Instance Attribute Details

#all_localesObject (readonly)

Returns the value of attribute all_locales.



45
46
47
# File 'lib/utopia/middleware/localization.rb', line 45

def all_locales
  @all_locales
end

#default_localeObject (readonly)

Returns the value of attribute default_locale.



46
47
48
# File 'lib/utopia/middleware/localization.rb', line 46

def default_locale
  @default_locale
end

Instance Method Details

#call(env) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/utopia/middleware/localization.rb', line 75

def call(env)
	# Check for a non-localized resource.
	if nonlocalized?(env)
		return @app.call(env)
	end
	
	# Otherwise, we need to check if the resource has been localized based on the request and referer parameters.
	path = Path.create(env["PATH_INFO"])
	env["utopia.localization"] = self

	referer_locale = named_locale(env['HTTP_REFERER'])
	request_locale = named_locale(path.basename)
	resource_name = Name.nonlocalized(path.basename, @all_locales).join(".")

	response = nil
	if request_locale
		env["utopia.current_locale"] = request_locale
		resource_path, response = check_resource(resource_name, request_locale, env)
	elsif referer_locale
		env["utopia.current_locale"] = referer_locale
		resource_path, response = check_resource(resource_name, referer_locale, env)
	end
	
	# If the previous checks failed, i.e. there was no request/referer locale 
	# or the response was 404 (i.e. no localised resource), we check for the
	# @default_locale
	if response == nil || response[0] >= 400
		env["utopia.current_locale"] = @default_locale
		resource_path, response = check_resource(resource_name, @default_locale, env)
	end

	# If the response is 2xx, we have a localised resource
	if response[0] < 300
		# If the original request was the same as the localized request,
		if path.basename == resource_path.basename
			# The resource URI is correct.
			return @app.call(env)
		else
			# Redirect to the correct resource URI.
			return [307, {"Location" => resource_path.to_s}, []]
		end
	elsif response[0] < 400
		# We have encountered a redirect while accessing the localized resource
		return response
	else
		# A localized resource was not found, return the unlocalised resource path,
		if path.basename == resource_name
			return @app.call(env)
		else
			return [307, {"Location" => (path.dirname + resource_name).to_s}, []]
		end
	end
end

#check_resource(resource_name, resource_locale, env) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/utopia/middleware/localization.rb', line 48

def check_resource(resource_name, resource_locale, env)
	localized_name = Name.localized(resource_name, resource_locale, @all_locales).join(".")
	localized_path = Path.create(env["PATH_INFO"]).dirname + localized_name

	localization_probe = env.dup
	localization_probe["REQUEST_METHOD"] = "HEAD"
	localization_probe["PATH_INFO"] = localized_path.to_s

	# Find out if a resource exists for the requested localization
	return [localized_path, @app.call(localization_probe)]
end

#named_locale(resource_name) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/utopia/middleware/localization.rb', line 37

def named_locale(resource_name)
	if resource_name
		Name.extract_locale(resource_name, @all_locales)
	else
		nil
	end
end

#nonlocalized?(env) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/utopia/middleware/localization.rb', line 60

def nonlocalized?(env)
	@nonlocalized.each do |pattern|
		case pattern
		when String
			return true if pattern == env["PATH_INFO"]
		when Regexp
			return true if pattern.match(env["PATH_INFO"])
		when pattern.respond_to?(:call)
			return true if pattern.call(env)
		end
	end
	
	return false
end