described_routes 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/README.rdoc +21 -20
- data/Rakefile +13 -12
- data/lib/described_routes.rb +1 -1
- data/lib/described_routes/helpers/described_routes_helper.rb +41 -30
- data/lib/described_routes/rails_controller.rb +7 -0
- data/test_rails_app/app/controllers/application_controller.rb +8 -1
- data/test_rails_app/app/controllers/users_controller.rb +8 -0
- data/test_rails_app/test/integration/headers_test.rb +35 -17
- metadata +12 -11
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
== DESCRIPTION
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
Features:
|
6
|
+
* Dynamic, framework-neutral, client-friendly <code>ResourceTemplate</code> metadata describing the path/URI structures of your whole site or of specific resources
|
7
|
+
* JSON, YAML and XML formats, also a bonus plain text report
|
8
|
+
* A link header-based discovery protocol, enabling clients to find <code>ResourceTemplate</code> metadata from the resources of any enabled controller
|
9
|
+
* Easy integration with Rails
|
8
10
|
|
9
11
|
== SYNOPSIS:
|
10
12
|
|
@@ -58,29 +60,35 @@ include full URI templates.
|
|
58
60
|
|
59
61
|
=== Run time
|
60
62
|
|
61
|
-
|
63
|
+
There are two integration steps for run time support:
|
64
|
+
|
65
|
+
1) Include the controller, perhaps in an initializer:
|
62
66
|
|
63
67
|
require 'described_routes/rails_controller'
|
64
68
|
|
65
|
-
Add the following route in config/routes.rb:
|
69
|
+
2) Add the following route in config/routes.rb:
|
66
70
|
|
67
71
|
map.resources :described_routes, :controller => "described_routes/rails"
|
68
72
|
|
69
73
|
You (or your client application) can now browse to any of the following top level addresses:
|
70
74
|
|
75
|
+
* .../described_routes
|
76
|
+
* .../described_routes.txt
|
71
77
|
* .../described_routes.json
|
72
78
|
* .../described_routes.xml
|
73
79
|
* .../described_routes.yaml
|
74
|
-
* .../described_routes.ytxt
|
75
80
|
|
76
81
|
and for the named route "users" (say):
|
77
82
|
|
83
|
+
* .../described_routes/users
|
84
|
+
* .../described_routes/users.txt
|
78
85
|
* .../described_routes/users.json
|
79
86
|
* .../described_routes/users.xml
|
80
87
|
* .../described_routes/users.yaml
|
81
|
-
* .../described_routes/users.txt
|
82
88
|
|
83
|
-
|
89
|
+
In the absence of content negotiation, requests to addresses without format extensions redirect to the respective .txt address.
|
90
|
+
|
91
|
+
If the application has a route named "root", run-time-generated data will include full URIs in <code>uri_template</code> attributes based on <code>root_url</code> in addition to the <code>path_template</code> attributes supported at build time.
|
84
92
|
|
85
93
|
Example:
|
86
94
|
|
@@ -165,21 +173,14 @@ JSON example (after pretty printing):
|
|
165
173
|
|
166
174
|
=== Link Generation
|
167
175
|
|
168
|
-
|
169
|
-
|
170
|
-
Generate HTML link elements by generated by adding
|
171
|
-
|
172
|
-
<%= link_elements %>
|
173
|
-
|
174
|
-
to the <head> part of you layout.
|
175
|
-
|
176
|
-
Generate link headers (see the draft spec http://tools.ietf.org/id/draft-nottingham-http-link-header-05.txt) by including
|
176
|
+
Generate link headers (see the draft spec http://tools.ietf.org/id/draft-nottingham-http-link-header-06.txt) by including
|
177
177
|
|
178
|
-
|
178
|
+
include DescribedRoutes::DescribedRoutesHelper
|
179
|
+
after_filter :set_link_header
|
179
180
|
|
180
|
-
in your controllers. You can do this once in ApplicationController to get this behaviour across all controllers.
|
181
|
+
in your controllers. You can do this once in ApplicationController to get this behaviour across all controllers, or in specific controllers (for example the one for the root resource).
|
181
182
|
|
182
|
-
See DescribedRoutes::DescribedRoutesHelper#link_data for configuration options.
|
183
|
+
See DescribedRoutes::DescribedRoutesHelper#link_data for configuration options; note however that you will need to define a new filter method if you wish to override the defaults. These are set to provide the minimum information necessary to support site discovery via resource-specific metadata links.
|
183
184
|
|
184
185
|
== DATA STRUCTURES and FORMATS
|
185
186
|
|
data/Rakefile
CHANGED
@@ -1,26 +1,27 @@
|
|
1
1
|
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
2
|
$:.push File.dirname(__FILE__) + '/lib'
|
3
3
|
require 'described_routes'
|
4
|
+
require 'hoe'
|
4
5
|
|
5
6
|
# Generate all the Rake tasks
|
6
7
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
7
|
-
$hoe = Hoe.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
$hoe = Hoe.spec 'described_routes' do
|
9
|
+
developer('Mike Burrows', 'mjb@asplake.co.uk')
|
10
|
+
self.readme_file = "README.rdoc"
|
11
|
+
self.changes = paragraphs_of("History.txt", 0..1).join("\n\n")
|
12
|
+
self.rubyforge_name = 'describedroutes'
|
13
|
+
self.url = 'http://positiveincline.com/?p=213'
|
14
|
+
self.extra_deps = [
|
14
15
|
['addressable','>= 2.1.0'],
|
15
16
|
]
|
16
|
-
|
17
|
+
self.extra_dev_deps = [
|
17
18
|
['newgem', ">= #{::Newgem::VERSION}"]
|
18
19
|
]
|
19
20
|
|
20
|
-
|
21
|
-
path = (
|
22
|
-
|
23
|
-
|
21
|
+
self.clean_globs |= %w[**/.DS_Store tmp *.log]
|
22
|
+
path = (rubyforge_name == name) ? rubyforge_name : "\#{rubyforge_name}/\#{name}"
|
23
|
+
self.remote_rdoc_dir = File.join(path.gsub(/^#{rubyforge_name}\/?/,''), 'rdoc')
|
24
|
+
self.rsync_args = '-av --delete --ignore-errors'
|
24
25
|
end
|
25
26
|
|
26
27
|
task :info do
|
data/lib/described_routes.rb
CHANGED
@@ -7,12 +7,12 @@ module DescribedRoutes
|
|
7
7
|
|
8
8
|
# The default options parameter to #link_elements; controls which links appear in html link elements
|
9
9
|
LINK_ELEMENT_OPTIONS = {
|
10
|
-
:self =>
|
10
|
+
:self => false, :describedby => true, :up => false, :related => false
|
11
11
|
}
|
12
12
|
|
13
13
|
# The default options parameter to #link_headers; controls which links appear in html link elements
|
14
14
|
LINK_HEADER_OPTIONS = {
|
15
|
-
:self =>
|
15
|
+
:self => false, :describedby => true, :up => false, :related => false
|
16
16
|
}
|
17
17
|
|
18
18
|
# get the resource template structure, initialised (once) from Rails routes
|
@@ -44,8 +44,12 @@ module DescribedRoutes
|
|
44
44
|
# Render link_data as <link <url> rel=<rel> ... type=<type>> elements. Add to the <head> part of your layout with:
|
45
45
|
# <%= link_elements %>
|
46
46
|
def link_elements(options=LINK_ELEMENT_OPTIONS)
|
47
|
-
link_data(options).map{|url, rels,
|
48
|
-
|
47
|
+
link_data(options).map{|url, rels, attrs|
|
48
|
+
[
|
49
|
+
%Q(<link href="#{url}"),
|
50
|
+
rels.map{|r| %Q(rel="#{r}")},
|
51
|
+
attrs.map{|k, v| %Q(#{k}="#{v}")}
|
52
|
+
].join(' ')
|
49
53
|
}.join("\n")
|
50
54
|
end
|
51
55
|
|
@@ -53,74 +57,81 @@ module DescribedRoutes
|
|
53
57
|
# response.headers["Link"] = link_header(options)
|
54
58
|
# or use #set_link_header
|
55
59
|
def link_header(options=LINK_HEADER_OPTIONS)
|
56
|
-
link_data(options).map{|url, rels,
|
57
|
-
|
60
|
+
link_data(options).map{|url, rels, attrs|
|
61
|
+
[
|
62
|
+
"<#{url}>",
|
63
|
+
rels.map{|r| %Q(rel="#{r}")},
|
64
|
+
attrs.map{|k, v| %Q(#{k}="#{v}")}
|
65
|
+
].join('; ')
|
58
66
|
}.join(', ')
|
59
67
|
end
|
60
68
|
|
61
69
|
# Sets a link header in the response
|
62
|
-
#
|
70
|
+
# after_filter :set_link_header
|
63
71
|
def set_link_header(options=LINK_HEADER_OPTIONS)
|
64
72
|
response.headers["Link"] = link_header(options)
|
65
73
|
end
|
66
74
|
|
67
75
|
# Returns an array of link information, each element containing
|
68
76
|
# 0) a URL
|
69
|
-
# 1) a
|
70
|
-
# 2) a
|
77
|
+
# 1) a list of link relation types (there can be more than one)
|
78
|
+
# 2) a hash of attributes, typically just one, either "role" (for regular resources) or "meta" (for metadata resources)
|
71
79
|
# The list of link relations types will contain a standard type ('self', 'up', 'describedby') &/or an extention type
|
72
80
|
# in the form "described_route_url(name)#rel", using the name and rel of the resource template.
|
73
81
|
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# [
|
77
|
-
# ['http://example.com/users/dojo', ['self'], 'user'],
|
78
|
-
# ['http://example.com/users', ['up'], 'users'],
|
79
|
-
# ['http://example.com/users/described_routes/user?user_id=dojo', ['describedby'], 'ResourceTemplate'],
|
80
|
-
# ['http://example.com/users/dojo/edit', ['edit', 'http://example.com/user/described_routes/user#edit'], 'edit_user'],
|
81
|
-
# ['http://example.com/users/dojo/edit', ['http://example.com/user/described_routes/user#profile'], 'user_profile']
|
82
|
-
# ]
|
83
|
-
#
|
84
|
-
# The output is filtered by the options hash, with members :self, :describedby, :describedby, :describedbywithparams, :up, :related.
|
82
|
+
# The output is filtered by the options hash, with members :self, :describedby, :up, :related.
|
85
83
|
# Rel values will include a short value (e.g. 'edit') if the template's rel has a mapping in REGISTERED_RELS.
|
86
84
|
#
|
87
85
|
def link_data(options)
|
88
86
|
result = []
|
89
87
|
rt = resource_template
|
90
88
|
if rt
|
89
|
+
type_prefix = described_routes_url + '#'
|
90
|
+
#
|
91
|
+
# For the application's root, the link with rel="describedby" has meta="ResourceTemplates" and it refers to a list of all
|
92
|
+
# top level resource templates. Otherwise, rel="describedby" has meta="ResourceTemplate" and it refers to a single resource
|
93
|
+
# template (together with any descendants).
|
94
|
+
#
|
91
95
|
if rt.name == 'root'
|
92
96
|
described_by = described_routes_url
|
93
97
|
related = resource_templates
|
98
|
+
meta = "ResourceTemplates"
|
94
99
|
else
|
95
100
|
described_by = described_route_url(rt.name)
|
96
101
|
related = rt.resource_templates
|
102
|
+
meta = "ResourceTemplate"
|
97
103
|
end
|
98
104
|
|
105
|
+
#
|
106
|
+
# Add any query parameters to the rel="describedby" link
|
107
|
+
#
|
99
108
|
if resource_parameters.empty?
|
100
109
|
described_by_with_params = described_by
|
101
110
|
else
|
102
111
|
described_by_with_params = described_by + '?' + resource_parameters.to_query
|
103
112
|
end
|
104
113
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
if options[:
|
110
|
-
|
111
|
-
|
114
|
+
# data for rel="self"
|
115
|
+
result << [request.url, ['self'], {'role' => type_prefix + rt.name}] if options[:self]
|
116
|
+
|
117
|
+
# data for rel="described_by"
|
118
|
+
result << [described_by_with_params, ['describedby'], {'meta' => meta}] if options[:describedby]
|
119
|
+
|
120
|
+
# data for rel="up"
|
112
121
|
if options[:up]
|
113
122
|
if rt.parent
|
114
|
-
result << [rt.parent.uri_for(resource_parameters), ['up'], type_prefix + rt.parent.name]
|
123
|
+
result << [rt.parent.uri_for(resource_parameters), ['up'], {'role' => type_prefix + rt.parent.name}]
|
115
124
|
elsif rt.name != 'root'
|
116
|
-
result << [root_url, ['up'], type_prefix +
|
125
|
+
result << [root_url, ['up'], {'role' => type_prefix + 'root'}]
|
117
126
|
end
|
118
127
|
end
|
128
|
+
|
129
|
+
# data for rel="related"
|
119
130
|
if options[:related]
|
120
131
|
related.expand_links(resource_parameters).map do |l|
|
121
132
|
if l.name != rt.name
|
122
133
|
rel = l.rel || l.name
|
123
|
-
result << [l.uri, REGISTERED_RELS[rel].to_a + [described_by + '#' + rel], type_prefix + l.name]
|
134
|
+
result << [l.uri, REGISTERED_RELS[rel].to_a + [described_by + '#' + rel], {'role' => type_prefix + l.name}]
|
124
135
|
end
|
125
136
|
end
|
126
137
|
end
|
@@ -6,6 +6,8 @@ module DescribedRoutes
|
|
6
6
|
class RailsController < ActionController::Base
|
7
7
|
include DescribedRoutes::DescribedRoutesHelper
|
8
8
|
|
9
|
+
after_filter :set_link_header
|
10
|
+
|
9
11
|
def index
|
10
12
|
expanded_templates = resource_templates.partial_expand(request.query_parameters)
|
11
13
|
|
@@ -32,5 +34,10 @@ module DescribedRoutes
|
|
32
34
|
format.xml { render :xml => resource_template.to_xml(Builder::XmlMarkup.new(:indent => 2)).target! }
|
33
35
|
end
|
34
36
|
end
|
37
|
+
|
38
|
+
def set_link_header
|
39
|
+
rel = request.path == described_routes_path ? "self" : "index"
|
40
|
+
response.headers["Link"] = %Q(<#{described_routes_url}>; rel="#{rel}"; meta="ResourceTemplates")
|
41
|
+
end
|
35
42
|
end
|
36
43
|
end
|
@@ -7,11 +7,18 @@ class ApplicationController < ActionController::Base
|
|
7
7
|
include DescribedRoutes::DescribedRoutesHelper
|
8
8
|
helper DescribedRoutes::DescribedRoutesHelper
|
9
9
|
|
10
|
-
|
10
|
+
after_filter :set_link_headers
|
11
|
+
|
11
12
|
layout "default"
|
12
13
|
|
13
14
|
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
14
15
|
|
15
16
|
# Scrub sensitive parameters from your log
|
16
17
|
# filter_parameter_logging :password
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def set_link_headers
|
22
|
+
set_link_header :self => true, :up => true, :describedby => true, :related => true
|
23
|
+
end
|
17
24
|
end
|
@@ -3,7 +3,15 @@ class UsersController < ApplicationController
|
|
3
3
|
render :text => "<h1>index</h1>", :layout => true
|
4
4
|
end
|
5
5
|
|
6
|
+
def new
|
7
|
+
render :text => "<h1>new</h1>", :layout => true
|
8
|
+
end
|
9
|
+
|
6
10
|
def show
|
7
11
|
render :text => "<h1>show #{params[:id]}</h1>", :layout => true
|
8
12
|
end
|
13
|
+
|
14
|
+
def edit
|
15
|
+
render :text => "<h1>edit #{params[:id]}</h1>", :layout => true
|
16
|
+
end
|
9
17
|
end
|
@@ -4,35 +4,53 @@ class DescribedRoutesRunTimeTest < ActionController::IntegrationTest
|
|
4
4
|
def test_root_headers
|
5
5
|
get "/"
|
6
6
|
assert_equal(
|
7
|
-
'<http://www.example.com/>; rel="self";
|
8
|
-
'<http://www.example.com/described_routes>; rel="describedby";
|
9
|
-
'<http://www.example.com/admin/products>; rel="http://www.example.com/described_routes#admin_products";
|
10
|
-
'<http://www.example.com/described_routes>; rel="http://www.example.com/described_routes#described_routes";
|
11
|
-
'<http://www.example.com/pages>; rel="http://www.example.com/described_routes#pages";
|
12
|
-
'<http://www.example.com/users>; rel="http://www.example.com/described_routes#users";
|
7
|
+
'<http://www.example.com/>; rel="self"; role="http://www.example.com/described_routes#root", ' +
|
8
|
+
'<http://www.example.com/described_routes>; rel="describedby"; meta="ResourceTemplates", ' +
|
9
|
+
'<http://www.example.com/admin/products>; rel="http://www.example.com/described_routes#admin_products"; role="http://www.example.com/described_routes#admin_products", ' +
|
10
|
+
'<http://www.example.com/described_routes>; rel="http://www.example.com/described_routes#described_routes"; role="http://www.example.com/described_routes#described_routes", ' +
|
11
|
+
'<http://www.example.com/pages>; rel="http://www.example.com/described_routes#pages"; role="http://www.example.com/described_routes#pages", ' +
|
12
|
+
'<http://www.example.com/users>; rel="http://www.example.com/described_routes#users"; role="http://www.example.com/described_routes#users"',
|
13
13
|
headers["Link"])
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_users_headers
|
17
17
|
get "/users"
|
18
18
|
assert_equal(
|
19
|
-
'<http://www.example.com/users>; rel="self";
|
20
|
-
'<http://www.example.com/described_routes/users>; rel="describedby";
|
21
|
-
'<http://www.example.com/>; rel="up";
|
22
|
-
'<http://www.example.com/users/new>; rel="http://www.example.com/described_routes/users#new_user";
|
19
|
+
'<http://www.example.com/users>; rel="self"; role="http://www.example.com/described_routes#users", ' +
|
20
|
+
'<http://www.example.com/described_routes/users>; rel="describedby"; meta="ResourceTemplate", ' +
|
21
|
+
'<http://www.example.com/>; rel="up"; role="http://www.example.com/described_routes#root", ' +
|
22
|
+
'<http://www.example.com/users/new>; rel="http://www.example.com/described_routes/users#new_user"; role="http://www.example.com/described_routes#new_user"',
|
23
|
+
headers["Link"])
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_new_user_headers
|
27
|
+
get "/users/new"
|
28
|
+
assert_equal(
|
29
|
+
'<http://www.example.com/users/new>; rel="self"; role="http://www.example.com/described_routes#new_user", ' +
|
30
|
+
'<http://www.example.com/described_routes/new_user>; rel="describedby"; meta="ResourceTemplate", ' +
|
31
|
+
'<http://www.example.com/users>; rel="up"; role="http://www.example.com/described_routes#users"',
|
23
32
|
headers["Link"])
|
24
33
|
end
|
25
34
|
|
26
35
|
def test_user_headers
|
27
36
|
get "/users/dojo"
|
28
37
|
assert_equal(
|
29
|
-
'<http://www.example.com/users/dojo>; rel="self";
|
30
|
-
'<http://www.example.com/described_routes/user>; rel="describedby";
|
31
|
-
'<http://www.example.com/
|
32
|
-
'<http://www.example.com/users>; rel="
|
33
|
-
'<http://www.example.com/users/dojo/
|
34
|
-
'<http://www.example.com/users/dojo/
|
35
|
-
'<http://www.example.com/users/dojo/profile>; rel="http://www.example.com/described_routes/user#profile"; type="http://www.example.com/described_routes#user_profile"',
|
38
|
+
'<http://www.example.com/users/dojo>; rel="self"; role="http://www.example.com/described_routes#user", ' +
|
39
|
+
'<http://www.example.com/described_routes/user?user_id=dojo>; rel="describedby"; meta="ResourceTemplate", ' +
|
40
|
+
'<http://www.example.com/users>; rel="up"; role="http://www.example.com/described_routes#users", ' +
|
41
|
+
'<http://www.example.com/users/dojo/edit>; rel="edit"; rel="http://www.example.com/described_routes/user#edit"; role="http://www.example.com/described_routes#edit_user", ' +
|
42
|
+
'<http://www.example.com/users/dojo/articles>; rel="http://www.example.com/described_routes/user#articles"; role="http://www.example.com/described_routes#user_articles", ' +
|
43
|
+
'<http://www.example.com/users/dojo/profile>; rel="http://www.example.com/described_routes/user#profile"; role="http://www.example.com/described_routes#user_profile"',
|
36
44
|
headers["Link"])
|
37
45
|
end
|
46
|
+
|
47
|
+
def test_edit_user_headers
|
48
|
+
get "/users/dojo/edit"
|
49
|
+
assert_equal(
|
50
|
+
'<http://www.example.com/users/dojo/edit>; rel="self"; role="http://www.example.com/described_routes#edit_user", ' +
|
51
|
+
'<http://www.example.com/described_routes/edit_user?user_id=dojo>; rel="describedby"; meta="ResourceTemplate", ' +
|
52
|
+
'<http://www.example.com/users/dojo>; rel="up"; role="http://www.example.com/described_routes#user"',
|
53
|
+
headers["Link"])
|
54
|
+
end
|
55
|
+
|
38
56
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: described_routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Burrows
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-26 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.5.1
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: hoe
|
@@ -40,12 +40,14 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
version: 2.3.2
|
44
44
|
version:
|
45
45
|
description: |-
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
Features:
|
47
|
+
* Dynamic, framework-neutral, client-friendly <code>ResourceTemplate</code> metadata describing the path/URI structures of your whole site or of specific resources
|
48
|
+
* JSON, YAML and XML formats, also a bonus plain text report
|
49
|
+
* A link header-based discovery protocol, enabling clients to find <code>ResourceTemplate</code> metadata from the resources of any enabled controller
|
50
|
+
* Easy integration with Rails
|
49
51
|
email:
|
50
52
|
- mjb@asplake.co.uk
|
51
53
|
executables: []
|
@@ -56,7 +58,6 @@ extra_rdoc_files:
|
|
56
58
|
- History.txt
|
57
59
|
- Manifest.txt
|
58
60
|
- PostInstall.txt
|
59
|
-
- README.rdoc
|
60
61
|
files:
|
61
62
|
- History.txt
|
62
63
|
- LICENSE
|
@@ -114,7 +115,7 @@ has_rdoc: true
|
|
114
115
|
homepage: http://positiveincline.com/?p=213
|
115
116
|
licenses: []
|
116
117
|
|
117
|
-
post_install_message:
|
118
|
+
post_install_message:
|
118
119
|
rdoc_options:
|
119
120
|
- --main
|
120
121
|
- README.rdoc
|
@@ -135,10 +136,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
136
|
requirements: []
|
136
137
|
|
137
138
|
rubyforge_project: describedroutes
|
138
|
-
rubygems_version: 1.3.
|
139
|
+
rubygems_version: 1.3.5
|
139
140
|
signing_key:
|
140
141
|
specification_version: 3
|
141
|
-
summary: Dynamic, framework-neutral metadata describing path/URI structures
|
142
|
+
summary: "Features: * Dynamic, framework-neutral, client-friendly <code>ResourceTemplate</code> metadata describing the path/URI structures of your whole site or of specific resources * JSON, YAML and XML formats, also a bonus plain text report * A link header-based discovery protocol, enabling clients to find <code>ResourceTemplate</code> metadata from the resources of any enabled controller * Easy integration with Rails"
|
142
143
|
test_files:
|
143
144
|
- test/test_described_routes.rb
|
144
145
|
- test/test_helper.rb
|