Skip to content

Commit 64c24a8

Browse files
committed
Merge pull request #238 from rfestag/add_named_captures_support
Added support for named captures
2 parents 7a22afc + f146b2b commit 64c24a8

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

documentation/routes.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ App = Webmachine::Application.new do |app|
2020
# but will not provide any path_info
2121
add ["orders", :*], OrderResource
2222

23+
# Will map to any path that matches the given components and regular expression
24+
# Any capture groups specified in the regex will be made available in
25+
# request.path_info[:captures. In this case, you would get one or two
26+
# values in :captures depending on whether your request looked like:
27+
# /orders/1/cancel
28+
# or
29+
# /orders/1/cancel.json
30+
add ["orders", :id, /([^.]*)\.?(.*)?/], OrderResource
31+
32+
# You can even use named captures with regular expressions. This will
33+
# automatically put the captures into path_info. In the below example,
34+
# you would get :id from the symbol, along with :action and :format
35+
# from the regex. :format in this case would be optional.
36+
add ["orders", :id, /(?<action>)[^.]*)\.?(?<format>.*)?/], OrderResource
37+
2338
# will map to any path
2439
add [:*], DefaultResource
2540
end
@@ -94,4 +109,4 @@ end
94109
request.path_info[:foo]
95110
=> "bar"
96111

97-
```
112+
```

lib/webmachine/dispatcher/route.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,14 @@ def bind(tokens, bindings)
122122
when Regexp === spec.first
123123
matches = spec.first.match URI.decode(tokens.first)
124124
if matches
125-
bindings[:captures] = (bindings[:captures] || []) + matches.captures
125+
if spec.first.named_captures.empty?
126+
bindings[:captures] = (bindings[:captures] || []) + matches.captures
127+
else
128+
spec.first.named_captures.reduce(bindings) do |bindings, (name, idxs)|
129+
bindings[name.to_sym] = matches.captures[idxs.first-1]
130+
bindings
131+
end
132+
end
126133
else
127134
return false
128135
end

spec/webmachine/dispatcher/route_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ def call(request)
219219
expect(request.path_info).to eq({:captures => ["bar", "json"]})
220220
end
221221
end
222+
context "with named capture regex" do
223+
subject { described_class.new(['foo', :bar, /(?<baz>[^.]+)\.(?<format>.*)/], resource) }
224+
let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz.json") }
225+
226+
it "should assign the captures path variables" do
227+
expect(request.path_info).to eq({bar: 'bar', baz: 'baz', format: "json"})
228+
end
229+
end
222230

223231
context "with a splat" do
224232
subject { described_class.new(['foo', :*], resource) }

0 commit comments

Comments
 (0)