sinatra-rroute 0.0.1 → 0.1.0
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.
- checksums.yaml +4 -4
- data/README.md +94 -18
- data/lib/sinatra/rroute.rb +55 -2
- data/lib/sinatra/rroute/version.rb +1 -1
- data/spec/controllers/init.rb +1 -0
- data/spec/controllers/nested.rb +17 -0
- data/spec/rroute_spec.rb +20 -0
- data/spec/test_app.rb +15 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 540d92d8facd0fc96d90dbd1ebc535e452f1fd02
|
|
4
|
+
data.tar.gz: 16f27c900d637268d325a4ad7e18c35686aff6da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5db8fe0b35667a730b571c68783d69f35f56d01103c766182971e8abbd2df5f97fa91e8c3a09c0a26a7cc55b909dba19e1a0aca269bad0b37f72db19dee8eefd
|
|
7
|
+
data.tar.gz: 7736ecdaab8375ea1756aa1611c7e20581d728e9789229349c638ade0c7132bd94b25fc8dbe572597831ba5a62d7910de4378db97ba09aa99ace99c10ebe85bb
|
data/README.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# Sinatra-rroute
|
|
2
2
|
|
|
3
|
-
Sinatra-rroute provides Rails-like routes for Sinatra. Using one of the
|
|
3
|
+
Sinatra-rroute provides Rails-like routes for Sinatra. Using one of the
|
|
4
|
+
`gget`/`ppost`/`ddelete`/... methods, a route is assigned a name, is mapped
|
|
5
|
+
to a controller-like method and has a mask to be used by the provided
|
|
6
|
+
`path` helper function. The `path` helper takes the name of a route, a set
|
|
7
|
+
of keyword-value mappings, applies them to the mask and gives back the
|
|
8
|
+
route with each keyword replaced by the associated value.
|
|
4
9
|
|
|
5
|
-
Routes can also be namespaced. Namespaces can be nested. There can be
|
|
10
|
+
Routes can also be namespaced. Namespaces can be nested. There can be
|
|
11
|
+
multiple namespaces per app.
|
|
6
12
|
|
|
7
13
|
## Setup
|
|
8
14
|
|
|
@@ -22,7 +28,8 @@ Routes can also be namespaced. Namespaces can be nested. There can be multiple n
|
|
|
22
28
|
|
|
23
29
|
### Route Mapping
|
|
24
30
|
|
|
25
|
-
Mapping routes to controller-like methods works by calling one of the
|
|
31
|
+
Mapping routes to controller-like methods works by calling one of the
|
|
32
|
+
sinatra-rroute mapping methods like so:
|
|
26
33
|
|
|
27
34
|
# This will call Sinatra's `get' method behind the scenes.
|
|
28
35
|
gget '/[uU]ser/:name/:age/?' => :user_info, :as =>
|
|
@@ -32,9 +39,16 @@ Mapping routes to controller-like methods works by calling one of the sinatra-rr
|
|
|
32
39
|
ppost '/[uU]ser/new/:name/:age/?' => :create_user, :as =>
|
|
33
40
|
:new_user, :mask => '/user/new/:name/:age/'
|
|
34
41
|
|
|
35
|
-
The above examples will map GET requests for routes matching the RegEx
|
|
42
|
+
The above examples will map GET requests for routes matching the RegEx
|
|
43
|
+
`'/[uU]ser/:name/:age/?'` to the function `user_info` and POST requests to
|
|
44
|
+
the route matching the RegEx `'/[uU]ser/new/:name/:age/?'` to the function
|
|
45
|
+
:create_user. The first route can be referenced as `user`, the second one
|
|
46
|
+
as `new_user`.
|
|
36
47
|
|
|
37
|
-
Here are all the supported mapping methods and their associated HTTP
|
|
48
|
+
Here are all the supported mapping methods and their associated HTTP
|
|
49
|
+
methods (all of them have the same signature, e.g.
|
|
50
|
+
`gget('/route/regex/?' => :controller_method, :as => :route_name, :mask =>
|
|
51
|
+
'/route/mask/')`):
|
|
38
52
|
|
|
39
53
|
|
|
40
54
|
| Rroute Method | HTTP Method |
|
|
@@ -51,18 +65,61 @@ Here are all the supported mapping methods and their associated HTTP methods (al
|
|
|
51
65
|
| ttrace | TRACE |
|
|
52
66
|
| cconnect | CONNECT |
|
|
53
67
|
|
|
54
|
-
*The validity of some of those HTTP methods may be debatable, but it is
|
|
68
|
+
*The validity of some of those HTTP methods may be debatable, but it is
|
|
69
|
+
nice to have them, nonetheless, in case you might need them one day.*
|
|
55
70
|
|
|
56
|
-
If you do not want to map routes to methods, but still give them names and
|
|
71
|
+
If you do not want to map routes to methods, but still give them names and
|
|
72
|
+
masks, you can use the `mmap` function in combination with Sinatra's
|
|
73
|
+
built-in `get`/`post`/`delete`/... functions:
|
|
57
74
|
|
|
58
75
|
# Signature: mmap(regex, mask, name)
|
|
59
76
|
get mmap('/user/:name/?', '/user/:name/', :user_info) do
|
|
60
77
|
# ...
|
|
61
78
|
end
|
|
62
79
|
|
|
80
|
+
**Referencing controllers...**
|
|
81
|
+
|
|
82
|
+
...works in two ways. Either they are referenced using
|
|
83
|
+
symbols for simple class/module level or global controllers or they are
|
|
84
|
+
referenced using strings representing nested controllers similar to the
|
|
85
|
+
`:to` option of Rails' `get`/`post`/... routing methods:
|
|
86
|
+
|
|
87
|
+
# Symbol reference
|
|
88
|
+
gget '/[uU]ser/:name/:age/?' => :user_info, :as =>
|
|
89
|
+
:user, :mask => '/user/:name/:age/'
|
|
90
|
+
|
|
91
|
+
# String reference to nested controller (instance method)
|
|
92
|
+
gget '/[uU]ser/:name/:age/?' => 'Very::Deeply::Nested#controller',
|
|
93
|
+
:as => :user, :mask => '/user/:name/:age/'
|
|
94
|
+
|
|
95
|
+
# String reference to nested controller (class method)
|
|
96
|
+
gget '/[uU]ser/:name/:age/?' => 'Very::Deeply::Nested::controller',
|
|
97
|
+
:as => :user, :mask => '/user/:name/:age/'
|
|
98
|
+
|
|
99
|
+
String references can point to either instance methods or class methods.
|
|
100
|
+
For instance methods, the class is automatically instanciated and the
|
|
101
|
+
method is called on this anonymous instance. So arguments can not be
|
|
102
|
+
supplied for this instance (this would arguably be bad controller design
|
|
103
|
+
anyway). Unlike with Rails,
|
|
104
|
+
|
|
105
|
+
- case is significant in string references
|
|
106
|
+
(`'UpperCase::DeeplyNested::controller'`), but
|
|
107
|
+
- strings can reference arbitrarily deeply nested controllers
|
|
108
|
+
(`'One::Two::Three::Four::Five::Six::Seven#controller'`).
|
|
109
|
+
|
|
110
|
+
Have in mind, that for sinatra-rroute to be able to reach controllers,
|
|
111
|
+
the controllers already have to be defined, i.e. modules/classes have to be
|
|
112
|
+
required *before* being referenced in a `gget`/`ppost`/`mmap` call.
|
|
113
|
+
|
|
63
114
|
### Namespacing
|
|
64
115
|
|
|
65
|
-
Sinatra-rroute comes with a `nnamespace` method which takes the name of a
|
|
116
|
+
Sinatra-rroute comes with a `nnamespace` method which takes the name of a
|
|
117
|
+
namespace and a block. Each route specified using one of the sinatra-rroute
|
|
118
|
+
mapping functions (`gget`/`ppost`/`ddelete`/, also `mmap`) inside the block
|
|
119
|
+
will be prefixed by the specified namespace prefix. Sinatra's built-in
|
|
120
|
+
`get`/`post`/`delete`/... functions can be used within a namespace block,
|
|
121
|
+
but are *not* affected by the namespacing. Namespaces can be nested.
|
|
122
|
+
*Prefixes do have to specify leading and/or trailing slashes explicitely!*
|
|
66
123
|
|
|
67
124
|
Here is an example:
|
|
68
125
|
|
|
@@ -82,7 +139,10 @@ Here is an example:
|
|
|
82
139
|
|
|
83
140
|
### Route Helper
|
|
84
141
|
|
|
85
|
-
Sinatra-rroute comes with a `path` helper function. It takes the name of a
|
|
142
|
+
Sinatra-rroute comes with a `path` helper function. It takes the name of a
|
|
143
|
+
route and a hash of key-value mappings and returns the path for that route
|
|
144
|
+
according to its mask. Each "token" in a mask will be replaced by the value
|
|
145
|
+
for the specified key in the mapping.
|
|
86
146
|
|
|
87
147
|
# Specify a route mapping.
|
|
88
148
|
gget '/[uU]ser/:name/:age/?' => :user_info, :as =>
|
|
@@ -90,7 +150,8 @@ Sinatra-rroute comes with a `path` helper function. It takes the name of a route
|
|
|
90
150
|
|
|
91
151
|
# Redirect to this route.
|
|
92
152
|
get '/friend/:name/:age/?' do
|
|
93
|
-
redirect to(path(:user, :name => params[:name], :age =>
|
|
153
|
+
redirect to(path(:user, :name => params[:name], :age =>
|
|
154
|
+
params[:age]))
|
|
94
155
|
end
|
|
95
156
|
|
|
96
157
|
# Generate a link for the route in the view.
|
|
@@ -98,23 +159,36 @@ Sinatra-rroute comes with a `path` helper function. It takes the name of a route
|
|
|
98
159
|
# This will render the following link:
|
|
99
160
|
# <a href="/user/John/32/">Get user info</a>
|
|
100
161
|
|
|
101
|
-
The helper can be used in your view files as well as in your
|
|
162
|
+
The helper can be used in your view files as well as in your
|
|
163
|
+
controller/model/application. It is handy for links, redirecting etc.
|
|
102
164
|
|
|
103
165
|
### Accessing Routes
|
|
104
166
|
|
|
105
|
-
The full hash of all route-method mappings is attached to your Sinatra
|
|
167
|
+
The full hash of all route-method mappings is attached to your Sinatra
|
|
168
|
+
app's `settings` object available through the `settings.app_paths`
|
|
169
|
+
variable.
|
|
106
170
|
|
|
107
|
-
*Note*: The full list of all routes is only available after the last call
|
|
171
|
+
*Note*: The full list of all routes is only available after the last call
|
|
172
|
+
of one of the sinatra-rroute mapping methods, of course.
|
|
108
173
|
|
|
109
|
-
*Note*: When mixing sinatra-rroute mapping methods
|
|
174
|
+
*Note*: When mixing sinatra-rroute mapping methods
|
|
175
|
+
(`gget`/`ppost`/`delete`/`mmap`/...) and Sinatra's built-in
|
|
176
|
+
`get`/`post`/`delete`/... the routes defined using the Sinatra built-ins
|
|
177
|
+
will *not* show up in `settings.app_paths`!
|
|
110
178
|
|
|
111
179
|
## Mixing With Sinatra and Other Extensions
|
|
112
180
|
|
|
113
|
-
Sinatra's built-in `get`/`post`/`delete`/... functions as well as other
|
|
181
|
+
Sinatra's built-in `get`/`post`/`delete`/... functions as well as other
|
|
182
|
+
route-related extensions do work fine in combination with sinatra-rroute as
|
|
183
|
+
long as they do not
|
|
114
184
|
|
|
115
185
|
- clash with sinatra-rroute's function names,
|
|
116
|
-
- fiddle with the `settings.app_paths` variable of your Sinatra app
|
|
117
|
-
- redefine/overload Sinatra's built-in `get`/`post`/`delete` functions
|
|
186
|
+
- fiddle with the `settings.app_paths` variable of your Sinatra app,
|
|
187
|
+
- redefine/overload Sinatra's built-in `get`/`post`/`delete` functions
|
|
188
|
+
without letting sinatra-rroute know or
|
|
189
|
+
- redefine/overload/fiddle with the
|
|
190
|
+
`rroute_call_nested_controller_from_string` method which handles nested
|
|
191
|
+
controller references.
|
|
118
192
|
|
|
119
193
|
## *What about the weird method names?*
|
|
120
194
|
|
|
@@ -122,4 +196,6 @@ The names are
|
|
|
122
196
|
|
|
123
197
|
- concise (as short as possible),
|
|
124
198
|
- consistent (same name generatiion scheme) and
|
|
125
|
-
- unobtrusive (they do not interfere with or overload Sinatra's and Rack's
|
|
199
|
+
- unobtrusive (they do not interfere with or overload Sinatra's and Rack's
|
|
200
|
+
built-in routing methods, they also do not interfere with other Sinatra
|
|
201
|
+
extensions).
|
data/lib/sinatra/rroute.rb
CHANGED
|
@@ -40,6 +40,51 @@ module Sinatra
|
|
|
40
40
|
end
|
|
41
41
|
path
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
# @visibility private
|
|
45
|
+
#
|
|
46
|
+
# Take the string representation of a nested instance method or of
|
|
47
|
+
# a class method and call the method.
|
|
48
|
+
#
|
|
49
|
+
# Notes:
|
|
50
|
+
#
|
|
51
|
+
# - The name is chosen to be long and unique enough to not be
|
|
52
|
+
# accidentially overwritten
|
|
53
|
+
# - Arguments are not supported as the methods to use this function
|
|
54
|
+
# on are controllers.
|
|
55
|
+
# - Unlike the `:to' option of Rails' `match' method (used by
|
|
56
|
+
# `get'/`post'/...), strings are case-sensitive.
|
|
57
|
+
# - Unlike the `:to' option of Rails' `match' method
|
|
58
|
+
# methods can be arbitrarily deeply nested.
|
|
59
|
+
#
|
|
60
|
+
# @param [String] string String representation of a method
|
|
61
|
+
#
|
|
62
|
+
# @example
|
|
63
|
+
#
|
|
64
|
+
# # Instance method
|
|
65
|
+
# rroute_call_nested_controller_from_string(
|
|
66
|
+
# 'Very::Deeply::Nested#controller')
|
|
67
|
+
#
|
|
68
|
+
# # Class method
|
|
69
|
+
# rroute_call_nested_controller_from_string(
|
|
70
|
+
# 'Very::Deeply::Nested::controller')
|
|
71
|
+
#
|
|
72
|
+
# @return [nil] Nothing.
|
|
73
|
+
def rroute_call_nested_controller_from_string(string)
|
|
74
|
+
method_sep = '#'
|
|
75
|
+
nesting_sep = '::'
|
|
76
|
+
if string =~ %r{#{method_sep}}
|
|
77
|
+
tokens = string.split(method_sep)
|
|
78
|
+
const = Kernel.const_get(tokens[0])
|
|
79
|
+
method = tokens[-1]
|
|
80
|
+
const.new.send(method.to_sym)
|
|
81
|
+
else
|
|
82
|
+
tokens = string.split(nesting_sep)
|
|
83
|
+
const = Kernel.const_get(tokens[0..-2].join(nesting_sep))
|
|
84
|
+
method = tokens[-1]
|
|
85
|
+
const.send(method.to_sym)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
43
88
|
end
|
|
44
89
|
end
|
|
45
90
|
|
|
@@ -108,7 +153,8 @@ module Sinatra
|
|
|
108
153
|
settings.app_prefixes.join
|
|
109
154
|
controller = nil
|
|
110
155
|
if mapping.values[0] != nil
|
|
111
|
-
controller = mapping.values[0].to_sym
|
|
156
|
+
# controller = mapping.values[0].to_sym
|
|
157
|
+
controller = mapping.values[0]
|
|
112
158
|
end
|
|
113
159
|
if mapping.keys[0].class == Regexp
|
|
114
160
|
mapping_regex = mapping.keys[0]
|
|
@@ -399,7 +445,14 @@ module Sinatra
|
|
|
399
445
|
# Adapt the RegEx representation.
|
|
400
446
|
value[:regex] = value[:regex].source
|
|
401
447
|
send(value[:http_method],
|
|
402
|
-
value[:regex])
|
|
448
|
+
value[:regex]) do
|
|
449
|
+
if value[:controller].class == Symbol
|
|
450
|
+
send value[:controller]
|
|
451
|
+
else
|
|
452
|
+
rroute_call_nested_controller_from_string(value[:controller]
|
|
453
|
+
.to_s)
|
|
454
|
+
end
|
|
455
|
+
end
|
|
403
456
|
end
|
|
404
457
|
end
|
|
405
458
|
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative 'nested'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class TestApp < Sinatra::Base
|
|
2
|
+
|
|
3
|
+
module Nested
|
|
4
|
+
class Controller
|
|
5
|
+
class Reference
|
|
6
|
+
def controller
|
|
7
|
+
'I am nested controller. 95475e78-f2c9-11e3-ba43-60eb69544a6d'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.another_controller
|
|
11
|
+
'I am also nested 98985e7e-f2c9-11e3-b9d9-60eb69544a6d'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
data/spec/rroute_spec.rb
CHANGED
|
@@ -80,6 +80,26 @@ request" do
|
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
describe "#gget (3)" do
|
|
84
|
+
it "successfully dispatches a GET request and defines a route mask
|
|
85
|
+
(using a nested controller reference - instance method)" do
|
|
86
|
+
get '/nested/controller/references'
|
|
87
|
+
expect(last_response).to be_ok
|
|
88
|
+
expect(last_response.body)
|
|
89
|
+
.to include('95475e78-f2c9-11e3-ba43-60eb69544a6d')
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "#gget (4)" do
|
|
94
|
+
it "successfully dispatches a GET request and defines a route mask
|
|
95
|
+
(using a nested controller reference - class method)" do
|
|
96
|
+
get '/nested/controller/references/another/one'
|
|
97
|
+
expect(last_response).to be_ok
|
|
98
|
+
expect(last_response.body)
|
|
99
|
+
.to include('98985e7e-f2c9-11e3-b9d9-60eb69544a6d')
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
83
103
|
describe "#ppost" do
|
|
84
104
|
it "successfully dispatches a POST request and defines a route mask" do
|
|
85
105
|
post "/user/new/#{@user[:name]}/#{@user[:age]}/"
|
data/spec/test_app.rb
CHANGED
|
@@ -190,4 +190,19 @@ class TestApp < Sinatra::Base
|
|
|
190
190
|
get mmap('/generate/paths/?', 'generate/paths/', :build_paths) do
|
|
191
191
|
'Paths have been generated.'
|
|
192
192
|
end
|
|
193
|
+
|
|
194
|
+
# Nested controller references
|
|
195
|
+
|
|
196
|
+
require 'controllers/init'
|
|
197
|
+
|
|
198
|
+
# Instance method
|
|
199
|
+
gget '/nested/controller/references' =>
|
|
200
|
+
'TestApp::Nested::Controller::Reference#controller', :as =>
|
|
201
|
+
:nested_controller_reference, :mask => '/nested/controller/references'
|
|
202
|
+
|
|
203
|
+
# Class method
|
|
204
|
+
gget '/nested/controller/references/another/one' =>
|
|
205
|
+
'TestApp::Nested::Controller::Reference::another_controller', :as =>
|
|
206
|
+
:another_nested_controller_reference, :mask =>
|
|
207
|
+
'/nested/controller/references/another/one'
|
|
193
208
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sinatra-rroute
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- nounch
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-06-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -65,6 +65,8 @@ files:
|
|
|
65
65
|
- lib/sinatra/rroute.rb
|
|
66
66
|
- lib/sinatra/rroute/version.rb
|
|
67
67
|
- rroute.gemspec
|
|
68
|
+
- spec/controllers/init.rb
|
|
69
|
+
- spec/controllers/nested.rb
|
|
68
70
|
- spec/rroute_spec.rb
|
|
69
71
|
- spec/test_app.rb
|
|
70
72
|
homepage: ''
|
|
@@ -92,6 +94,8 @@ signing_key:
|
|
|
92
94
|
specification_version: 4
|
|
93
95
|
summary: Rails-style routes with names, namespaces and `path' helper.
|
|
94
96
|
test_files:
|
|
97
|
+
- spec/controllers/init.rb
|
|
98
|
+
- spec/controllers/nested.rb
|
|
95
99
|
- spec/rroute_spec.rb
|
|
96
100
|
- spec/test_app.rb
|
|
97
101
|
has_rdoc:
|