rack-rewrite-dynamic 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,36 +8,87 @@ module Rack
|
|
8
8
|
|
9
9
|
def perform(match, rack_env)
|
10
10
|
if !(match[1] =~ /assets/)
|
11
|
-
filter_parts = match
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
filter_parts = parse_filter_parts(match)
|
12
|
+
build_return_path(filter_parts, rack_env)
|
13
|
+
else
|
14
|
+
original_path(rack_env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def build_return_path(filter_parts, rack_env)
|
20
|
+
if filter_parts.length > 0
|
21
|
+
slugs = filter_parts.map do |candidate|
|
22
|
+
find_sluggable(candidate)
|
15
23
|
end
|
24
|
+
|
25
|
+
filter_params = {}
|
16
26
|
if !slugs.include?(nil)
|
17
|
-
filter_params = {}
|
18
27
|
slugs.each do |s|
|
19
|
-
filter_params
|
20
|
-
filter_params["#{s[:sluggable_type].underscore}_ids"] << s[:sluggable_id]
|
28
|
+
add_filter_param(filter_params, s)
|
21
29
|
end
|
22
|
-
return "/#{@opts[:target]}?#{filter_params.to_query}"
|
23
30
|
end
|
31
|
+
|
32
|
+
return "/#{@opts[:target]}?#{filter_params.to_query}" if filter_params.length > 0
|
24
33
|
end
|
25
|
-
|
26
|
-
|
34
|
+
original_path(rack_env)
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_filter_parts(match)
|
38
|
+
slug_index = 0
|
39
|
+
|
40
|
+
@opts[:url_parts].map do |url_part|
|
41
|
+
if url_part.keys.include?(:static)
|
42
|
+
# :)
|
43
|
+
elsif url_part.keys.include?(:prefix) || url_part.keys.include?(:suffix)
|
44
|
+
slug_index += 1
|
45
|
+
if match[slug_index]
|
46
|
+
match[slug_index].chomp(url_part[:separator])
|
47
|
+
end
|
48
|
+
elsif url_part.keys.include?(:groups)
|
49
|
+
if match[slug_index+1]
|
50
|
+
slug_index += 1
|
51
|
+
match[slug_index..-1].each_with_index.map { |slug_group, i| slug_group.split(url_part[:groups][i][:separator]) if slug_group }.flatten
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end.flatten.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_filter_param(filter_params, slug)
|
58
|
+
filter_params["#{slug[:sluggable_type].underscore}_ids"] ||= []
|
59
|
+
filter_params["#{slug[:sluggable_type].underscore}_ids"] << slug[:sluggable_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
def slug_group_matcher_string(groups)
|
63
|
+
groups.map do |group|
|
64
|
+
"(#{group[:prefix]}#{filter_string}#{group[:suffix]})?-?"
|
65
|
+
end.join
|
66
|
+
end
|
67
|
+
|
68
|
+
def slug_group_matcher(groups)
|
69
|
+
Regexp.new(slug_group_matcher_string(groups))
|
27
70
|
end
|
28
|
-
end
|
29
71
|
|
30
|
-
private
|
31
72
|
def build_match_string
|
32
|
-
match_string = '
|
33
|
-
match_string <<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
73
|
+
match_string = '^\/'
|
74
|
+
match_string << @opts[:url_parts].map do |url_part|
|
75
|
+
if url_part.keys.include?(:static)
|
76
|
+
"(#{url_part[:static]})"
|
77
|
+
elsif url_part.keys.include?(:prefix) || url_part.keys.include?(:suffix)
|
78
|
+
"#{url_part[:prefix]}#{filter_string}#{('?' unless url_part[:required])}#{url_part[:separator]}?#{url_part[:suffix]}"
|
79
|
+
elsif url_part.keys.include?(:groups)
|
80
|
+
slug_group_matcher_string(url_part[:groups]).to_s
|
81
|
+
end + suburl_separator(url_part[:required])
|
82
|
+
end.join
|
83
|
+
|
84
|
+
match_string.chomp!(suburl_separator(true))
|
85
|
+
match_string.chomp(suburl_separator(false))
|
38
86
|
end
|
39
87
|
def filter_string
|
40
|
-
'([^\/]+)'
|
88
|
+
'(?<slug_groups>[^\/]+)'
|
89
|
+
end
|
90
|
+
def suburl_separator(required = false)
|
91
|
+
"\\/#{'?' unless required}"
|
41
92
|
end
|
42
93
|
end
|
43
94
|
end
|
@@ -13,40 +13,97 @@ describe Rack::Rewrite::Dynamic::FilterRewrite do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
let(:opts) do
|
17
|
-
{
|
18
|
-
separator: '-', target: 'outfits', suffix: 'outfits'
|
19
|
-
}
|
20
|
-
end
|
21
|
-
subject { Rack::Rewrite::Dynamic::FilterRewrite.new(opts) }
|
22
16
|
let(:base) { mock(:base) }
|
17
|
+
let(:rack_env) { { 'REQUEST_URI' => 'some/path' } }
|
23
18
|
|
19
|
+
let(:opts) { {} }
|
20
|
+
subject { Rack::Rewrite::Dynamic::FilterRewrite.new(opts) }
|
24
21
|
its(:opts) { should eq(opts) }
|
25
22
|
|
26
|
-
it 'should
|
27
|
-
|
28
|
-
subject.
|
23
|
+
it 'should return the original request if assets' do
|
24
|
+
match = ['', 'assets']
|
25
|
+
subject.perform(match, rack_env).should eq('some/path')
|
29
26
|
end
|
30
27
|
|
31
|
-
|
32
|
-
let(:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
context 'handle SEO urls like /slug1-slug2-outfits/red-green-colored-from-nike-and-red-mountain' do
|
29
|
+
let(:opts) do
|
30
|
+
{
|
31
|
+
target: 'outfits',
|
32
|
+
url_parts: [{suffix: 'outfits', separator: '-'},
|
33
|
+
{
|
34
|
+
groups: [
|
35
|
+
{suffix: '-colored', separator: '-'},
|
36
|
+
{prefix: 'from-', separator: '-and-'}
|
37
|
+
]
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}
|
37
41
|
end
|
42
|
+
let(:match) { ['', 'business-', 'red-darkblue', 'nike-and-red-mountain'] }
|
38
43
|
|
39
|
-
it 'should
|
40
|
-
|
41
|
-
subject.
|
44
|
+
it 'should apply rewrite' do
|
45
|
+
base.should_receive(:rewrite).with(/^\/(?<slug_groups>[^\/]+)?-?outfits\/?((?<slug_groups>[^\/]+)-colored)?-?(from-(?<slug_groups>[^\/]+))?-?/, anything)
|
46
|
+
subject.apply_rewrite(base)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should perform rewrite' do
|
50
|
+
subject.stub(:find_sluggable).with('business'){ { sluggable_type: 'outfit_category', sluggable_id: 42 } }
|
51
|
+
subject.stub(:find_sluggable).with('red'){ { sluggable_type: 'color', sluggable_id: 42 } }
|
52
|
+
subject.stub(:find_sluggable).with('darkblue'){ { sluggable_type: 'color', sluggable_id: 43 } }
|
53
|
+
subject.stub(:find_sluggable).with('nike'){ { sluggable_type: 'brand', sluggable_id: 42 } }
|
54
|
+
subject.stub(:find_sluggable).with('red-mountain'){ { sluggable_type: 'brand', sluggable_id: 43 } }
|
55
|
+
|
56
|
+
subject.perform(match, rack_env).should eq('/outfits?brand_ids%5B%5D=42&brand_ids%5B%5D=43&color_ids%5B%5D=42&color_ids%5B%5D=43&outfit_category_ids%5B%5D=42')
|
42
57
|
end
|
43
58
|
|
44
59
|
it 'should not return path if slug wasn not found' do
|
45
60
|
subject.stub(:find_sluggable)
|
46
|
-
subject.perform(match, rack_env).should
|
61
|
+
subject.perform(match, rack_env).should eq('some/path')
|
47
62
|
end
|
48
|
-
|
49
63
|
end
|
50
64
|
|
65
|
+
context 'handle SEO urls like /fashion-items/slug1-slug2/red-green-colored-from-nike-or-red-mountain' do
|
66
|
+
let(:opts) do
|
67
|
+
{
|
68
|
+
target: 'products',
|
69
|
+
url_parts: [{static: 'fashion-items'},
|
70
|
+
{suffix: '', separator: '-'},
|
71
|
+
{
|
72
|
+
groups: [
|
73
|
+
{suffix: '-colored', separator: '-'},
|
74
|
+
{prefix: 'from-', separator: '-or-'}
|
75
|
+
]
|
76
|
+
}
|
77
|
+
]
|
78
|
+
}
|
79
|
+
end
|
80
|
+
let(:match) { ['', 'tops-shirts', 'blue-red-darkgray', 'nike-or-adidas'] }
|
81
|
+
|
82
|
+
before :each do
|
83
|
+
subject.stub(:find_sluggable).with('tops-shirts'){ { sluggable_type: 'product_category', sluggable_id: 42 } }
|
84
|
+
subject.stub(:find_sluggable).with('blue'){ { sluggable_type: 'color', sluggable_id: 42 } }
|
85
|
+
subject.stub(:find_sluggable).with('red'){ { sluggable_type: 'color', sluggable_id: 43 } }
|
86
|
+
subject.stub(:find_sluggable).with('darkgray'){ { sluggable_type: 'color', sluggable_id: 44 } }
|
87
|
+
subject.stub(:find_sluggable).with('nike'){ { sluggable_type: 'brand', sluggable_id: 42 } }
|
88
|
+
subject.stub(:find_sluggable).with('adidas'){ { sluggable_type: 'brand', sluggable_id: 43 } }
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should apply rewrite' do
|
92
|
+
base.should_receive(:rewrite).with(/^\/(fashion-items)\/?(?<slug_groups>[^\/]+)?-?\/?((?<slug_groups>[^\/]+)-colored)?-?(from-(?<slug_groups>[^\/]+))?-?/, anything)
|
93
|
+
subject.apply_rewrite(base)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should perform the rewrite' do
|
97
|
+
subject.perform(match, rack_env).should eq('/products?brand_ids%5B%5D=42&brand_ids%5B%5D=43&color_ids%5B%5D=42&color_ids%5B%5D=43&color_ids%5B%5D=44&product_category_ids%5B%5D=42')
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should perform the rewrite even if some of the slug groups are missing' do
|
101
|
+
match = ['', 'tops-shirts', 'blue-red-darkgray']
|
102
|
+
|
103
|
+
subject.perform(match, rack_env).should eq('/products?color_ids%5B%5D=42&color_ids%5B%5D=43&color_ids%5B%5D=44&product_category_ids%5B%5D=42')
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
end
|
51
108
|
end
|
52
109
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-rewrite-dynamic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack-rewrite
|