wovnrb 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -0
- data/lib/wovnrb.rb +14 -3
- data/lib/wovnrb/headers.rb +20 -14
- data/lib/wovnrb/settings.rb +9 -1
- data/lib/wovnrb/version.rb +1 -1
- data/test/lib/headers_test.rb +43 -0
- data/test/lib/wovnrb_test.rb +112 -1
- data/test/test_helper.rb +4 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1d7702d09e87b697371b1c5609040910fa9383d55a05ebac5d1ae668b04013c
|
4
|
+
data.tar.gz: c18162741b2cbb82137687cd6b9a0176cc576cae8230c3720d4ebd19df065656
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3285cbeb773a4415e82fd8cc06b375d4e3e0adea37c2e026699f401cd2692a67972aef40513a209b1d39686fb52664bc3964d6d8be69088d716b960f9e8e1ef3
|
7
|
+
data.tar.gz: ea6c7b83a2a2b6c16c5d7d5310ec17e021a4e1b87524cc60de3794230890aeb8742205e7197ba9bbd74d492092523f59bcd48f576440729e6a014919d11f4313
|
data/README.md
CHANGED
@@ -82,6 +82,7 @@ lang_param_name | | 'wovn'
|
|
82
82
|
query | | []
|
83
83
|
ignore_class | | []
|
84
84
|
translate_fragment | | true
|
85
|
+
ignore_paths | | []
|
85
86
|
|
86
87
|
### 2.1. project_token
|
87
88
|
|
@@ -161,6 +162,17 @@ This option allows to disable translating partial HTML content. By default,
|
|
161
162
|
partial HTML content is translated but no widget snippet is added. Set
|
162
163
|
`translate_fragment` to `false` to prevent translating partial HTML content.
|
163
164
|
|
165
|
+
### 2.9 ignore_paths
|
166
|
+
|
167
|
+
This parameter tells WOVN.rb to not localize content withing given directories.
|
168
|
+
|
169
|
+
The directories given will only be matched against the beginning of the URL path.
|
170
|
+
|
171
|
+
For instance, if you want to not localize the admin directory of your website, you should add the following to you WOVN.rb configuration.
|
172
|
+
```
|
173
|
+
'ignore_paths' => ['/admin/']
|
174
|
+
```
|
175
|
+
|
164
176
|
## 3. Contributing
|
165
177
|
|
166
178
|
1. Fork it ( https://github.com/WOVNio/wovnrb/fork )
|
data/lib/wovnrb.rb
CHANGED
@@ -32,14 +32,21 @@ module Wovnrb
|
|
32
32
|
|
33
33
|
@env = env
|
34
34
|
headers = Headers.new(env, @store.settings)
|
35
|
+
default_lang = @store.settings['default_lang']
|
35
36
|
return @app.call(env) if @store.settings['test_mode'] && @store.settings['test_url'] != headers.url
|
36
37
|
|
37
38
|
# redirect if the path is set to the default language (for SEO purposes)
|
38
|
-
if headers.path_lang ==
|
39
|
-
redirect_headers = headers.redirect(
|
39
|
+
if headers.path_lang == default_lang
|
40
|
+
redirect_headers = headers.redirect(default_lang)
|
40
41
|
return [307, redirect_headers, ['']]
|
41
42
|
end
|
42
43
|
|
44
|
+
# if path containing language code is ignored, do nothing
|
45
|
+
if headers.lang_code != default_lang && ignore_path?(headers.unmasked_pathname_without_trailing_slash)
|
46
|
+
status, res_headers, body = @app.call(env)
|
47
|
+
|
48
|
+
return output(headers, status, res_headers, body)
|
49
|
+
end
|
43
50
|
# pass to application
|
44
51
|
status, res_headers, body = @app.call(headers.request_out)
|
45
52
|
|
@@ -51,7 +58,7 @@ module Wovnrb
|
|
51
58
|
return output(headers, status, res_headers, body) if request.params['wovn_disable'] == true
|
52
59
|
|
53
60
|
@store.settings.update_dynamic_settings!(request.params)
|
54
|
-
return output(headers, status, res_headers, body) if
|
61
|
+
return output(headers, status, res_headers, body) if ignore_path?(headers.pathname)
|
55
62
|
|
56
63
|
body = switch_lang(headers, body) unless status.to_s =~ /^1|302/
|
57
64
|
|
@@ -105,6 +112,10 @@ module Wovnrb
|
|
105
112
|
!html_body.xpath('//html[@wovn-ignore]').empty?
|
106
113
|
end
|
107
114
|
|
115
|
+
def ignore_path?(path)
|
116
|
+
@store.settings['ignore_globs'].ignore?(path)
|
117
|
+
end
|
118
|
+
|
108
119
|
# Checks if a given HTML body is an Accelerated Mobile Page (AMP).
|
109
120
|
# To do so, it looks at the required attributes for the HTML tag:
|
110
121
|
# https://www.ampproject.org/docs/tutorials/create/basic_markup.
|
data/lib/wovnrb/headers.rb
CHANGED
@@ -39,7 +39,6 @@ module Wovnrb
|
|
39
39
|
else
|
40
40
|
@env['HTTP_HOST']
|
41
41
|
end
|
42
|
-
@env['wovnrb.target_lang'] = lang_code
|
43
42
|
@host = settings['url_pattern'] == 'subdomain' ? remove_lang(@host, lang_code) : @host
|
44
43
|
@pathname, @query = @env['REQUEST_URI'].split('?')
|
45
44
|
@pathname = settings['url_pattern'] == 'path' ? remove_lang(@pathname, lang_code) : @pathname
|
@@ -66,6 +65,10 @@ module Wovnrb
|
|
66
65
|
@redis_url = "#{@host}#{@pathname}#{@query}"
|
67
66
|
end
|
68
67
|
|
68
|
+
def unmasked_pathname_without_trailing_slash
|
69
|
+
@unmasked_pathname.chomp('/')
|
70
|
+
end
|
71
|
+
|
69
72
|
# Get the language code of the current request
|
70
73
|
#
|
71
74
|
# @return [String] The lang code of the current page
|
@@ -150,6 +153,7 @@ module Wovnrb
|
|
150
153
|
end
|
151
154
|
|
152
155
|
def request_out(_def_lang = @settings['default_lang'])
|
156
|
+
@env['wovnrb.target_lang'] = lang_code
|
153
157
|
case @settings['url_pattern']
|
154
158
|
when 'query'
|
155
159
|
@env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI']) if @env.key?('REQUEST_URI')
|
@@ -203,19 +207,21 @@ module Wovnrb
|
|
203
207
|
r = Regexp.new('//' + @host)
|
204
208
|
lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
|
205
209
|
if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
210
|
+
unless @settings['ignore_globs'].ignore?(headers['Location'])
|
211
|
+
case @settings['url_pattern']
|
212
|
+
when 'query'
|
213
|
+
headers['Location'] += if headers['Location'] =~ /\?/
|
214
|
+
'&'
|
215
|
+
else
|
216
|
+
'?'
|
217
|
+
end
|
218
|
+
headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
|
219
|
+
when 'subdomain'
|
220
|
+
headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, '//' + lang_code + '.\1')
|
221
|
+
# when 'path'
|
222
|
+
else
|
223
|
+
headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, '\1/' + lang_code)
|
224
|
+
end
|
219
225
|
end
|
220
226
|
end
|
221
227
|
headers
|
data/lib/wovnrb/settings.rb
CHANGED
@@ -7,7 +7,7 @@ module Wovnrb
|
|
7
7
|
|
8
8
|
def [](key)
|
9
9
|
return @dynamic_settings[key] if @dynamic_settings.key?(key)
|
10
|
-
return ignore_globs if key == 'ignore_globs'
|
10
|
+
return IgnoreGlobsWrapper.new(ignore_globs) if key == 'ignore_globs'
|
11
11
|
|
12
12
|
super(key)
|
13
13
|
end
|
@@ -35,5 +35,13 @@ module Wovnrb
|
|
35
35
|
'wovn_token' => 'project_token',
|
36
36
|
'wovn_ignore_paths' => 'ignore_paths'
|
37
37
|
}.freeze
|
38
|
+
|
39
|
+
class IgnoreGlobsWrapper < Array
|
40
|
+
def ignore?(uri)
|
41
|
+
path = Addressable::URI.parse(uri).path
|
42
|
+
|
43
|
+
any? { |glob| glob.match?(path) }
|
44
|
+
end
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
data/lib/wovnrb/version.rb
CHANGED
data/test/lib/headers_test.rb
CHANGED
@@ -279,6 +279,49 @@ module Wovnrb
|
|
279
279
|
assert_equal('http://wovn.io/test', env['HTTP_REFERER'])
|
280
280
|
end
|
281
281
|
|
282
|
+
def test_out_should_add_lang_code_to_redirection
|
283
|
+
sut = Wovnrb::Headers.new(
|
284
|
+
Wovnrb.get_env(
|
285
|
+
'SERVER_NAME' => 'wovn.io',
|
286
|
+
'REQUEST_URI' => '/ja/test',
|
287
|
+
'HTTP_REFERER' => 'http://wovn.io/ja/test'
|
288
|
+
),
|
289
|
+
Wovnrb.get_settings(
|
290
|
+
'default_lang' => 'en',
|
291
|
+
'supported_langs' => %w[en ja],
|
292
|
+
'url_pattern' => 'path',
|
293
|
+
'url_pattern_reg' => '/(?<lang>[^/.?]+)'
|
294
|
+
)
|
295
|
+
)
|
296
|
+
headers = {
|
297
|
+
'Location' => 'http://wovn.io/'
|
298
|
+
}
|
299
|
+
|
300
|
+
assert_equal('http://wovn.io/ja/', sut.out(headers)['Location'])
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_out_should_not_add_lang_code_to_ignored_redirection
|
304
|
+
sut = Wovnrb::Headers.new(
|
305
|
+
Wovnrb.get_env(
|
306
|
+
'SERVER_NAME' => 'wovn.io',
|
307
|
+
'REQUEST_URI' => '/ja/test',
|
308
|
+
'HTTP_REFERER' => 'http://wovn.io/ja/test'
|
309
|
+
),
|
310
|
+
Wovnrb.get_settings(
|
311
|
+
'default_lang' => 'en',
|
312
|
+
'supported_langs' => %w[en ja],
|
313
|
+
'url_pattern' => 'path',
|
314
|
+
'url_pattern_reg' => '/(?<lang>[^/.?]+)',
|
315
|
+
'ignore_paths' => ['/static/']
|
316
|
+
)
|
317
|
+
)
|
318
|
+
headers = {
|
319
|
+
'Location' => 'http://wovn.io/static/'
|
320
|
+
}
|
321
|
+
|
322
|
+
assert_equal('http://wovn.io/static/', sut.out(headers)['Location'])
|
323
|
+
end
|
324
|
+
|
282
325
|
def test_out_http_referer_subdomain_with_custom_lang_code
|
283
326
|
Store.instance.update_settings('custom_lang_aliases' => { 'ja' => 'staging-ja' })
|
284
327
|
h = Wovnrb::Headers.new(
|
data/test/lib/wovnrb_test.rb
CHANGED
@@ -108,8 +108,119 @@ HTML
|
|
108
108
|
assert_switch_lang('en', 'ja', body, body, false)
|
109
109
|
end
|
110
110
|
|
111
|
+
def test_call_without_path_ignored_should_change_environment
|
112
|
+
settings = {
|
113
|
+
'project_token' => '123456',
|
114
|
+
'url_pattern' => 'path',
|
115
|
+
'default_lang' => 'ja',
|
116
|
+
'supported_langs' => %w[ja en],
|
117
|
+
'ignore_paths' => ['/en/ignored']
|
118
|
+
}
|
119
|
+
env = {
|
120
|
+
'rack.input' => '',
|
121
|
+
'rack.request.query_string' => '',
|
122
|
+
'rack.request.query_hash' => {},
|
123
|
+
'HTTP_HOST' => 'test.com',
|
124
|
+
'REQUEST_URI' => '/en/not_ignored',
|
125
|
+
'PATH_INFO' => '/en/not_ignored'
|
126
|
+
}
|
127
|
+
|
128
|
+
assert_call_affects_env(settings, env, mock_api: true, affected: true)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_call_with_path_ignored_with_language_code_should_change_environment
|
132
|
+
settings = {
|
133
|
+
'project_token' => '123456',
|
134
|
+
'url_pattern' => 'path',
|
135
|
+
'default_lang' => 'ja',
|
136
|
+
'supported_langs' => %w[ja en],
|
137
|
+
'ignore_paths' => ['/en/ignored']
|
138
|
+
}
|
139
|
+
env = {
|
140
|
+
'rack.input' => '',
|
141
|
+
'rack.request.query_string' => '',
|
142
|
+
'rack.request.query_hash' => {},
|
143
|
+
'HTTP_HOST' => 'test.com',
|
144
|
+
'REQUEST_URI' => '/ignored',
|
145
|
+
'PATH_INFO' => '/ignored'
|
146
|
+
}
|
147
|
+
|
148
|
+
assert_call_affects_env(settings, env, mock_api: false, affected: true)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_call_with_path_ignored_without_language_code_should_change_environment
|
152
|
+
settings = {
|
153
|
+
'project_token' => '123456',
|
154
|
+
'url_pattern' => 'path',
|
155
|
+
'default_lang' => 'ja',
|
156
|
+
'supported_langs' => %w[ja en],
|
157
|
+
'ignore_paths' => ['/ignored']
|
158
|
+
}
|
159
|
+
env = {
|
160
|
+
'rack.input' => '',
|
161
|
+
'rack.request.query_string' => '',
|
162
|
+
'rack.request.query_hash' => {},
|
163
|
+
'HTTP_HOST' => 'test.com',
|
164
|
+
'REQUEST_URI' => '/en/ignored',
|
165
|
+
'PATH_INFO' => '/en/ignored'
|
166
|
+
}
|
167
|
+
|
168
|
+
assert_call_affects_env(settings, env, mock_api: false, affected: true)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_call_with_path_ignored_without_language_code_in_original_language_should_change_environment
|
172
|
+
settings = {
|
173
|
+
'project_token' => '123456',
|
174
|
+
'url_pattern' => 'path',
|
175
|
+
'default_lang' => 'ja',
|
176
|
+
'supported_langs' => %w[ja en],
|
177
|
+
'ignore_paths' => ['/ignored']
|
178
|
+
}
|
179
|
+
env = {
|
180
|
+
'rack.input' => '',
|
181
|
+
'rack.request.query_string' => '',
|
182
|
+
'rack.request.query_hash' => {},
|
183
|
+
'HTTP_HOST' => 'test.com',
|
184
|
+
'REQUEST_URI' => '/ignored',
|
185
|
+
'PATH_INFO' => '/ignored'
|
186
|
+
}
|
187
|
+
|
188
|
+
assert_call_affects_env(settings, env, mock_api: false, affected: true)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_call_with_path_ignored_should_not_change_environment
|
192
|
+
settings = {
|
193
|
+
'project_token' => '123456',
|
194
|
+
'url_pattern' => 'path',
|
195
|
+
'default_lang' => 'ja',
|
196
|
+
'supported_langs' => %w[ja en],
|
197
|
+
'ignore_paths' => ['/en/ignored']
|
198
|
+
}
|
199
|
+
env = {
|
200
|
+
'rack.input' => '',
|
201
|
+
'rack.request.query_string' => '',
|
202
|
+
'rack.request.query_hash' => {},
|
203
|
+
'HTTP_HOST' => 'test.com',
|
204
|
+
'REQUEST_URI' => '/en/ignored',
|
205
|
+
'PATH_INFO' => '/en/ignored'
|
206
|
+
}
|
207
|
+
|
208
|
+
assert_call_affects_env(settings, env, mock_api: false, affected: false)
|
209
|
+
end
|
210
|
+
|
111
211
|
private
|
112
212
|
|
213
|
+
def assert_call_affects_env(settings, env, mock_api:, affected:)
|
214
|
+
app_mock = get_app
|
215
|
+
sut = Wovnrb::Interceptor.new(app_mock, settings)
|
216
|
+
unaffected_env = env
|
217
|
+
|
218
|
+
mock_translation_api_response('', '') if mock_api
|
219
|
+
sut.call(env.clone)
|
220
|
+
|
221
|
+
assert_equal(unaffected_env != app_mock.env, affected)
|
222
|
+
end
|
223
|
+
|
113
224
|
def assert_switch_lang(original_lang, target_lang, body, expected_body, api_expected = true)
|
114
225
|
subdomain = target_lang == original_lang ? '' : "#{target_lang}."
|
115
226
|
interceptor = Wovnrb::Interceptor.new(get_app)
|
@@ -160,7 +271,7 @@ HTML
|
|
160
271
|
end
|
161
272
|
|
162
273
|
class RackMock
|
163
|
-
attr_accessor :params
|
274
|
+
attr_accessor :params, :env
|
164
275
|
|
165
276
|
def initialize(opts = {})
|
166
277
|
@params = {}
|
data/test/test_helper.rb
CHANGED
@@ -59,7 +59,8 @@ module Wovnrb
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def get_settings(options = {})
|
62
|
-
settings =
|
62
|
+
settings = Wovnrb::Store.default_settings
|
63
|
+
|
63
64
|
settings['project_token'] = 'OHYx9'
|
64
65
|
settings['url_pattern'] = 'path'
|
65
66
|
settings['url_pattern_reg'] = '/(?<lang>[^/.?]+)'
|
@@ -68,7 +69,8 @@ module Wovnrb
|
|
68
69
|
settings['api_url'] = 'http://localhost/v0/values'
|
69
70
|
settings['default_lang'] = 'en'
|
70
71
|
settings['supported_langs'] = %w[en ja]
|
71
|
-
|
72
|
+
|
73
|
+
Wovnrb::Settings.new.merge(settings.merge(options))
|
72
74
|
end
|
73
75
|
|
74
76
|
def get_env(options = {})
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wovnrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Sandford
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-10-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|