rack-rewrite-dynamic 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
@@ -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
|