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.



44
45
46
47
48
49
50
51
# File 'lib/utopia/middleware/localization.rb', line 44

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.



61
62
63
# File 'lib/utopia/middleware/localization.rb', line 61

def all_locales
  @all_locales
end

#default_localeObject (readonly)

Returns the value of attribute default_locale.



62
63
64
# File 'lib/utopia/middleware/localization.rb', line 62

def default_locale
  @default_locale
end

Instance Method Details

#call(env) ⇒ Object



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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/utopia/middleware/localization.rb', line 91

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



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

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



53
54
55
56
57
58
59
# File 'lib/utopia/middleware/localization.rb', line 53

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

#nonlocalized?(env) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/utopia/middleware/localization.rb', line 76

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