sinatra-contrib 1.4.7 → 2.0.0.beta1
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 +27 -16
- data/Rakefile +0 -1
- data/lib/sinatra/config_file.rb +8 -2
- data/lib/sinatra/content_for.rb +63 -1
- data/lib/sinatra/contrib.rb +1 -1
- data/lib/sinatra/contrib/version.rb +1 -12
- data/lib/sinatra/cookies.rb +1 -1
- data/lib/sinatra/link_header.rb +2 -2
- data/lib/sinatra/namespace.rb +90 -18
- data/lib/sinatra/reloader.rb +15 -1
- data/lib/sinatra/required_params.rb +71 -0
- data/lib/sinatra/respond_with.rb +7 -5
- data/sinatra-contrib.gemspec +14 -10
- data/spec/capture_spec.rb +5 -5
- data/spec/config_file/key_value.yml +1 -0
- data/spec/config_file_spec.rb +27 -13
- data/spec/content_for/footer.haml +1 -1
- data/spec/content_for/footer.slim +1 -1
- data/spec/content_for_spec.rb +65 -36
- data/spec/cookies_spec.rb +167 -173
- data/spec/extension_spec.rb +4 -4
- data/spec/json_spec.rb +11 -11
- data/spec/link_header_spec.rb +13 -13
- data/spec/multi_route_spec.rb +13 -13
- data/spec/namespace_spec.rb +190 -140
- data/spec/reloader_spec.rb +56 -31
- data/spec/required_params_spec.rb +68 -0
- data/spec/respond_with_spec.rb +58 -56
- data/spec/streaming_spec.rb +57 -57
- metadata +37 -22
- data/lib/sinatra/decompile.rb +0 -127
- data/spec/decompile_spec.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2219eae01829dc23fe37858de893ee0bae5ae98
|
4
|
+
data.tar.gz: 04ee39f956e7420d07cbc39f853dc97f43a9702b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c2e640a53fd704cb2fe4f152da9dac0b75bc69b59386ce805b30f2e7e9716dcebbaf493f9f63738cf57407515082dcf4f6bdbde142546708356fb5423434c23
|
7
|
+
data.tar.gz: b35240ae66107dc1ebdd39e69a6efaebe6580ec852bf8f552b0c6f0e28404636b5ba3fafba3ccf0c84358b954772fc7c76204e8801f4f4348b35d20d42f3e075
|
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
|
1
|
+
# Sinatra::Contrib
|
2
2
|
|
3
3
|
Collection of common Sinatra extensions, semi-officially supported.
|
4
4
|
|
5
|
-
|
5
|
+
## Goals
|
6
6
|
|
7
7
|
* For every future Sinatra release, have at least one fully compatible release
|
8
8
|
* High code quality, high test coverage
|
9
9
|
* Include plugins people usually ask for a lot
|
10
10
|
|
11
|
-
|
11
|
+
## Included extensions
|
12
12
|
|
13
|
-
|
13
|
+
### Common Extensions
|
14
14
|
|
15
15
|
These are common extension which will not add significant overhead or change any
|
16
16
|
behavior of already existing APIs. They do not add any dependencies not already
|
@@ -49,34 +49,45 @@ Currently included:
|
|
49
49
|
logger instance using +logger+ setting. That logger then will
|
50
50
|
be available as #logger helper method in your routes and views.
|
51
51
|
|
52
|
-
|
52
|
+
* `sinatra/required_params`: Ensure if required query parameters exist
|
53
|
+
|
54
|
+
### Custom Extensions
|
53
55
|
|
54
56
|
These extensions may add additional dependencies and enhance the behavior of the
|
55
57
|
existing APIs.
|
56
58
|
|
57
59
|
Currently included:
|
58
60
|
|
59
|
-
* `sinatra/decompile`: Recreates path patterns from Sinatra's internal data
|
60
|
-
structures (used by other extensions).
|
61
|
-
|
62
61
|
* `sinatra/reloader`: Automatically reloads Ruby files on code changes.
|
63
62
|
|
64
|
-
|
63
|
+
### Other Tools
|
65
64
|
|
66
65
|
* `sinatra/extension`: Mixin for writing your own Sinatra extensions.
|
67
66
|
|
68
67
|
* `sinatra/test_helpers`: Helper methods to ease testing your Sinatra
|
69
68
|
application. Partly extracted from Sinatra. Testing framework agnostic
|
70
69
|
|
71
|
-
|
72
|
-
|
70
|
+
## Installation
|
71
|
+
|
72
|
+
Add `gem 'sinatra-contrib'` to *Gemfile*, then execute `bundle install`.
|
73
73
|
|
74
74
|
If you don't use Bundler, install the gem manually by executing `gem install sinatra-contrib` in your command line.
|
75
75
|
|
76
|
+
### Git
|
77
|
+
|
78
|
+
If you want to use the gem from git, for whatever reason, you can do the following:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
github 'sinatra/sinatra' do
|
82
|
+
gem 'sinatra-contrib'
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
Within this block you can also specify other gems from this git repository.
|
76
87
|
|
77
|
-
|
88
|
+
## Usage
|
78
89
|
|
79
|
-
|
90
|
+
### Classic Style
|
80
91
|
|
81
92
|
A single extension (example: sinatra-content-for):
|
82
93
|
|
@@ -99,7 +110,7 @@ require 'sinatra'
|
|
99
110
|
require 'sinatra/contrib/all'
|
100
111
|
```
|
101
112
|
|
102
|
-
|
113
|
+
### Modular Style
|
103
114
|
|
104
115
|
A single extension (example: sinatra-content-for):
|
105
116
|
|
@@ -138,7 +149,7 @@ class MyApp < Sinatra::Base
|
|
138
149
|
end
|
139
150
|
```
|
140
151
|
|
141
|
-
|
152
|
+
### Documentation
|
142
153
|
|
143
154
|
For more info check the [official docs](http://www.sinatrarb.com/contrib/) and
|
144
|
-
[api docs](http://rubydoc.info/gems/sinatra-contrib
|
155
|
+
[api docs](http://www.rubydoc.info/gems/sinatra-contrib).
|
data/Rakefile
CHANGED
@@ -57,7 +57,6 @@ task :release => :gemspec do
|
|
57
57
|
gem push sinatra-contrib*.gem &&
|
58
58
|
git commit --allow-empty -a -m '#{Sinatra::Contrib::VERSION} release' &&
|
59
59
|
git tag -s v#{Sinatra::Contrib::VERSION} -m '#{Sinatra::Contrib::VERSION} release' &&
|
60
|
-
git tag -s #{Sinatra::Contrib::VERSION} -m '#{Sinatra::Contrib::VERSION} release' &&
|
61
60
|
git push && (git push origin master || true) &&
|
62
61
|
git push --tags && (git push origin --tags || true)
|
63
62
|
SH
|
data/lib/sinatra/config_file.rb
CHANGED
@@ -128,9 +128,9 @@ module Sinatra
|
|
128
128
|
Dir.chdir(root || '.') do
|
129
129
|
paths.each do |pattern|
|
130
130
|
Dir.glob(pattern) do |file|
|
131
|
+
raise UnsupportedConfigType unless ['.yml', '.erb'].include?(File.extname(file))
|
131
132
|
$stderr.puts "loading config file '#{file}'" if logging?
|
132
|
-
document = IO.read(file)
|
133
|
-
document = ERB.new(document).result if file.split('.').include?('erb')
|
133
|
+
document = ERB.new(IO.read(file)).result
|
134
134
|
yaml = config_for_env(YAML.load(document)) || {}
|
135
135
|
yaml.each_pair do |key, value|
|
136
136
|
for_env = config_for_env(value)
|
@@ -141,6 +141,12 @@ module Sinatra
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
+
class UnsupportedConfigType < Exception
|
145
|
+
def message
|
146
|
+
'Invalid config file type, use .yml or .yml.erb'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
144
150
|
private
|
145
151
|
|
146
152
|
# Given a +hash+ with some application configuration it returns the
|
data/lib/sinatra/content_for.rb
CHANGED
@@ -27,6 +27,15 @@ module Sinatra
|
|
27
27
|
# # layout.erb
|
28
28
|
# <%= yield_content :some_key %>
|
29
29
|
#
|
30
|
+
# If you have provided +yield_content+ with a block and no content for the
|
31
|
+
# specified key is found, it will render the results of the block provided
|
32
|
+
# to yield_content.
|
33
|
+
#
|
34
|
+
# # layout.erb
|
35
|
+
# <%= yield_content :some_key_with_no_content do %>
|
36
|
+
# <chunk of="default html">...</chunk>
|
37
|
+
# <% end %>
|
38
|
+
#
|
30
39
|
# === Classic Application
|
31
40
|
#
|
32
41
|
# To use the helpers in a classic application all you need to do is require
|
@@ -59,6 +68,46 @@ module Sinatra
|
|
59
68
|
# layout, inside the <head> tag, and each view can call <tt>content_for</tt>
|
60
69
|
# setting the appropriate set of tags that should be added to the layout.
|
61
70
|
#
|
71
|
+
# == Limitations
|
72
|
+
#
|
73
|
+
# Due to the rendering process limitation using <tt><%= yield_content %></tt>
|
74
|
+
# from within nested templates do not work above the <tt><%= yield %> statement.
|
75
|
+
# For more details https://github.com/sinatra/sinatra-contrib/issues/140#issuecomment-48831668
|
76
|
+
#
|
77
|
+
# # app.rb
|
78
|
+
# get '/' do
|
79
|
+
# erb :body, :layout => :layout do
|
80
|
+
# erb :foobar
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# # foobar.erb
|
85
|
+
# <% content_for :one do %>
|
86
|
+
# <script>
|
87
|
+
# alert('one');
|
88
|
+
# </script>
|
89
|
+
# <% end %>
|
90
|
+
# <% content_for :two do %>
|
91
|
+
# <script>
|
92
|
+
# alert('two');
|
93
|
+
# </script>
|
94
|
+
# <% end %>
|
95
|
+
#
|
96
|
+
# Using <tt><%= yield_content %></tt> before <tt><%= yield %></tt> will cause only the second
|
97
|
+
# alert to display:
|
98
|
+
#
|
99
|
+
# # body.erb
|
100
|
+
# # Display only second alert
|
101
|
+
# <%= yield_content :one %>
|
102
|
+
# <%= yield %>
|
103
|
+
# <%= yield_content :two %>
|
104
|
+
#
|
105
|
+
# # body.erb
|
106
|
+
# # Display both alerts
|
107
|
+
# <%= yield %>
|
108
|
+
# <%= yield_content :one %>
|
109
|
+
# <%= yield_content :two %>
|
110
|
+
#
|
62
111
|
module ContentFor
|
63
112
|
include Capture
|
64
113
|
|
@@ -68,6 +117,10 @@ module Sinatra
|
|
68
117
|
# <script type="text/javascript" src="/foo.js"></script>
|
69
118
|
# <% end %>
|
70
119
|
#
|
120
|
+
# You can also pass an immediate value instead of a block:
|
121
|
+
#
|
122
|
+
# <% content_for :title, "foo" %>
|
123
|
+
#
|
71
124
|
# You can call +content_for+ multiple times with the same key
|
72
125
|
# (in the example +:head+), and when you render the blocks for
|
73
126
|
# that key all of them will be rendered, in the same order you
|
@@ -75,7 +128,8 @@ module Sinatra
|
|
75
128
|
#
|
76
129
|
# Your blocks can also receive values, which are passed to them
|
77
130
|
# by <tt>yield_content</tt>
|
78
|
-
def content_for(key, &block)
|
131
|
+
def content_for(key, value = nil, &block)
|
132
|
+
block ||= proc { |*| value }
|
79
133
|
content_blocks[key.to_sym] << capture_later(&block)
|
80
134
|
end
|
81
135
|
|
@@ -93,6 +147,13 @@ module Sinatra
|
|
93
147
|
content_blocks[key.to_sym].any?
|
94
148
|
end
|
95
149
|
|
150
|
+
# Unset a named block of content. For example:
|
151
|
+
#
|
152
|
+
# <% clear_content_for :head %>
|
153
|
+
def clear_content_for(key)
|
154
|
+
content_blocks.delete(key.to_sym) if content_for?(key)
|
155
|
+
end
|
156
|
+
|
96
157
|
# Render the captured blocks for a given key. For example:
|
97
158
|
#
|
98
159
|
# <head>
|
@@ -111,6 +172,7 @@ module Sinatra
|
|
111
172
|
# Would pass <tt>1</tt> and <tt>2</tt> to all the blocks registered
|
112
173
|
# for <tt>:head</tt>.
|
113
174
|
def yield_content(key, *args)
|
175
|
+
return yield(*args) if block_given? && content_blocks[key.to_sym].empty?
|
114
176
|
content_blocks[key.to_sym].map { |b| capture(*args, &b) }.join
|
115
177
|
end
|
116
178
|
|
data/lib/sinatra/contrib.rb
CHANGED
@@ -19,13 +19,13 @@ module Sinatra
|
|
19
19
|
helpers :JSON
|
20
20
|
helpers :LinkHeader
|
21
21
|
helpers :Streaming
|
22
|
+
helpers :RequiredParams
|
22
23
|
end
|
23
24
|
|
24
25
|
##
|
25
26
|
# Other extensions you don't want to be loaded unless needed.
|
26
27
|
module Custom
|
27
28
|
# register :Compass
|
28
|
-
register :Decompile
|
29
29
|
register :Reloader
|
30
30
|
end
|
31
31
|
|
@@ -1,17 +1,6 @@
|
|
1
1
|
module Sinatra
|
2
2
|
module Contrib
|
3
|
-
|
4
|
-
VERSION
|
5
|
-
end
|
6
|
-
|
7
|
-
SIGNATURE = [1, 4, 7]
|
8
|
-
VERSION = SIGNATURE.join('.')
|
9
|
-
|
10
|
-
VERSION.extend Comparable
|
11
|
-
def VERSION.<=>(other)
|
12
|
-
other = other.split('.').map { |i| i.to_i } if other.respond_to? :split
|
13
|
-
SIGNATURE <=> Array(other)
|
14
|
-
end
|
3
|
+
VERSION = ::Sinatra::VERSION
|
15
4
|
end
|
16
5
|
end
|
17
6
|
|
data/lib/sinatra/cookies.rb
CHANGED
data/lib/sinatra/link_header.rb
CHANGED
@@ -90,7 +90,7 @@ module Sinatra
|
|
90
90
|
link = (response["Link"] ||= "")
|
91
91
|
|
92
92
|
urls.map do |url|
|
93
|
-
link << "
|
93
|
+
link << ",\n" unless link.empty?
|
94
94
|
link << (http_pattern % url)
|
95
95
|
html_pattern % url
|
96
96
|
end.join "\n"
|
@@ -117,7 +117,7 @@ module Sinatra
|
|
117
117
|
def link_headers
|
118
118
|
yield if block_given?
|
119
119
|
return "" unless response.include? "Link"
|
120
|
-
response["Link"].
|
120
|
+
response["Link"].split(",\n").map do |line|
|
121
121
|
url, *opts = line.split(';').map(&:strip)
|
122
122
|
"<link href=\"#{url[1..-2]}\" #{opts.join " "} />"
|
123
123
|
end.join "\n"
|
data/lib/sinatra/namespace.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'backports'
|
2
2
|
require 'sinatra/base'
|
3
|
-
require '
|
3
|
+
require 'mustermann'
|
4
4
|
|
5
5
|
module Sinatra
|
6
6
|
|
@@ -48,6 +48,14 @@ module Sinatra
|
|
48
48
|
# # More admin routes...
|
49
49
|
# end
|
50
50
|
#
|
51
|
+
# Regex is also accepted:
|
52
|
+
#
|
53
|
+
# namespace /\/posts\/([^\/&?]+)\// do
|
54
|
+
# get { haml :blog }
|
55
|
+
#
|
56
|
+
# # More blog routes...
|
57
|
+
# end
|
58
|
+
#
|
51
59
|
# When you define a filter or an error handler, or register an extension or a
|
52
60
|
# set of helpers within a namespace, they only affect the routes defined in
|
53
61
|
# it. For instance, lets define a before filter to prevent the access of
|
@@ -89,6 +97,18 @@ module Sinatra
|
|
89
97
|
# # More admin routes...
|
90
98
|
# end
|
91
99
|
#
|
100
|
+
# Redirecting within the namespace can be done using redirect_to:
|
101
|
+
#
|
102
|
+
# namespace '/admin' do
|
103
|
+
# get '/foo' do
|
104
|
+
# redirect_to '/bar' # Redirects to /admin/bar
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# get '/foo' do
|
108
|
+
# redirect '/bar' # Redirects to /bar
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#
|
92
112
|
# === Classic Application Setup
|
93
113
|
#
|
94
114
|
# To be able to use namespaces in a classic application all you need to do is
|
@@ -97,7 +117,8 @@ module Sinatra
|
|
97
117
|
# require "sinatra"
|
98
118
|
# require "sinatra/namespace"
|
99
119
|
#
|
100
|
-
#
|
120
|
+
# namespace '/users' do
|
121
|
+
# end
|
101
122
|
#
|
102
123
|
# === Modular Application Setup
|
103
124
|
#
|
@@ -110,9 +131,60 @@ module Sinatra
|
|
110
131
|
# class MyApp < Sinatra::Base
|
111
132
|
# register Sinatra::Namespace
|
112
133
|
#
|
113
|
-
#
|
134
|
+
# namespace '/users' do
|
135
|
+
# end
|
114
136
|
# end
|
115
137
|
#
|
138
|
+
# === Within an extension
|
139
|
+
#
|
140
|
+
# To be able to use namespaces within an extension, you need to first create
|
141
|
+
# an extension. This includes defining the `registered(app)` method in the
|
142
|
+
# module.
|
143
|
+
#
|
144
|
+
# require 'sinatra/base' # For creating Sinatra extensions
|
145
|
+
# require 'sinatra/namespace' # To create namespaces
|
146
|
+
#
|
147
|
+
# module Zomg # Keep everything under "Zomg" namespace for sanity
|
148
|
+
# module Routes # Define a new "Routes" module
|
149
|
+
#
|
150
|
+
# self.registered(app)
|
151
|
+
# # First, register the Namespace extension
|
152
|
+
# app.register Sinatra::Namespace
|
153
|
+
#
|
154
|
+
# # This defines an `/api` namespace on the application
|
155
|
+
# app.namespace '/api' do
|
156
|
+
# get '/users' do
|
157
|
+
# # do something with `GET "/api/users"`
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# end
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# # Lastly, register the extension to use in our app
|
165
|
+
# Sinatra.register Routes
|
166
|
+
# end
|
167
|
+
#
|
168
|
+
# In order to use this extension, is the same as any other Sinatra extension:
|
169
|
+
#
|
170
|
+
# module Zomg
|
171
|
+
# # Define our app class, we use modular app for this example
|
172
|
+
# class App < Sinatra::Base
|
173
|
+
# # this gives us all the namespaces we defined earlier
|
174
|
+
# register Routes
|
175
|
+
#
|
176
|
+
# get '/' do
|
177
|
+
# "Welcome to my application!"
|
178
|
+
# end
|
179
|
+
# end
|
180
|
+
# end
|
181
|
+
#
|
182
|
+
# Zomg::App.run! # Don't forget to start your app ;)
|
183
|
+
#
|
184
|
+
# Phew! That was a mouthful.
|
185
|
+
#
|
186
|
+
# I hope that helps you use `Sinatra::Namespace` in every way imaginable!
|
187
|
+
#
|
116
188
|
module Namespace
|
117
189
|
def self.new(base, pattern, conditions = {}, &block)
|
118
190
|
Module.new do
|
@@ -137,6 +209,10 @@ module Sinatra
|
|
137
209
|
def template_cache
|
138
210
|
super.fetch(:nested, @namespace) { Tilt::Cache.new }
|
139
211
|
end
|
212
|
+
|
213
|
+
def redirect_to(uri, *args)
|
214
|
+
redirect("#{@namespace.pattern}#{uri}", *args)
|
215
|
+
end
|
140
216
|
end
|
141
217
|
|
142
218
|
module SharedMethods
|
@@ -147,7 +223,6 @@ module Sinatra
|
|
147
223
|
|
148
224
|
module NamespacedMethods
|
149
225
|
include SharedMethods
|
150
|
-
include Sinatra::Decompile
|
151
226
|
attr_reader :base, :templates
|
152
227
|
|
153
228
|
def self.prefixed(*names)
|
@@ -187,9 +262,10 @@ module Sinatra
|
|
187
262
|
end
|
188
263
|
|
189
264
|
def error(*codes, &block)
|
190
|
-
args = Sinatra::Base.send(:compile!, "ERROR",
|
265
|
+
args = Sinatra::Base.send(:compile!, "ERROR", /.*/, block)
|
191
266
|
codes = codes.map { |c| Array(c) }.flatten
|
192
267
|
codes << Exception if codes.empty?
|
268
|
+
codes << Sinatra::NotFound if codes.include?(404)
|
193
269
|
|
194
270
|
codes.each do |c|
|
195
271
|
errors = @errors[c] ||= []
|
@@ -226,6 +302,10 @@ module Sinatra
|
|
226
302
|
template name, &block
|
227
303
|
end
|
228
304
|
|
305
|
+
def pattern
|
306
|
+
@pattern
|
307
|
+
end
|
308
|
+
|
229
309
|
private
|
230
310
|
|
231
311
|
def app
|
@@ -246,22 +326,14 @@ module Sinatra
|
|
246
326
|
end
|
247
327
|
|
248
328
|
def prefixed_path(a, b)
|
249
|
-
return a || b ||
|
250
|
-
|
251
|
-
a, b = regexpify(a), regexpify(b) unless a.class == b.class
|
252
|
-
path = a.class.new "#{a}#{b}"
|
253
|
-
path = /^#{path}$/ if path.is_a? Regexp and base == app
|
254
|
-
path
|
255
|
-
end
|
329
|
+
return a || b || /.*/ unless a and b
|
330
|
+
return Mustermann.new(b) if a == /.*/
|
256
331
|
|
257
|
-
|
258
|
-
pattern = Sinatra::Base.send(:compile, pattern).first.inspect
|
259
|
-
pattern.gsub! /^\/(\^|\\A)?|(\$|\\z)?\/$/, ''
|
260
|
-
Regexp.new pattern
|
332
|
+
Mustermann.new(a) + Mustermann.new(b)
|
261
333
|
end
|
262
334
|
|
263
335
|
def prefixed(method, pattern = nil, conditions = {}, &block)
|
264
|
-
default =
|
336
|
+
default = /.*/ if method == :before or method == :after
|
265
337
|
pattern, conditions = compile pattern, conditions, default
|
266
338
|
result = base.send(method, pattern, conditions, &block)
|
267
339
|
invoke_hook :route_added, method.to_s.upcase, pattern, block
|
@@ -281,7 +353,7 @@ module Sinatra
|
|
281
353
|
include SharedMethods
|
282
354
|
end
|
283
355
|
|
284
|
-
def self.
|
356
|
+
def self.extended(base)
|
285
357
|
base.extend BaseMethods
|
286
358
|
end
|
287
359
|
end
|