sinatra-contrib 1.4.7 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 07b51967ed5d44b1b33b30808e889bea7f108f23
4
- data.tar.gz: 10bb9a0e8d0242f9b965925831faddb891621366
3
+ metadata.gz: a2219eae01829dc23fe37858de893ee0bae5ae98
4
+ data.tar.gz: 04ee39f956e7420d07cbc39f853dc97f43a9702b
5
5
  SHA512:
6
- metadata.gz: a1cf5ddaab8baa205ddd02411904e7c7eac393573a352f0a9be0757797a60e07ff9ce7a2d84b870ca7495724ac8bf116f788c517ed0b0023c5823d492071a7d7
7
- data.tar.gz: d7c55267680752f344a9248d3af5ef8440689edd415c08a31324cb3e8c290e18418df275afc8b7e7dc8b55d4026b94a47581c1ee3dd14beef04c48d5ab1b2519
6
+ metadata.gz: 5c2e640a53fd704cb2fe4f152da9dac0b75bc69b59386ce805b30f2e7e9716dcebbaf493f9f63738cf57407515082dcf4f6bdbde142546708356fb5423434c23
7
+ data.tar.gz: b35240ae66107dc1ebdd39e69a6efaebe6580ec852bf8f552b0c6f0e28404636b5ba3fafba3ccf0c84358b954772fc7c76204e8801f4f4348b35d20d42f3e075
data/README.md CHANGED
@@ -1,16 +1,16 @@
1
- [![Build Status](https://secure.travis-ci.org/sinatra/sinatra-contrib.png)](http://travis-ci.org/sinatra/sinatra-contrib)
1
+ # Sinatra::Contrib
2
2
 
3
3
  Collection of common Sinatra extensions, semi-officially supported.
4
4
 
5
- # Goals
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
- # Included extensions
11
+ ## Included extensions
12
12
 
13
- ## Common Extensions
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
- ## Custom Extensions
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
- ## Other Tools
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
- # Installation
72
- Add `gem 'sinatra-contrib'` to *Gemfile*, then execute `bundle install`.
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
- # Usage
88
+ ## Usage
78
89
 
79
- ## Classic Style
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
- ## Modular Style
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
- ## Documentation
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/1.4.0/frames).
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
@@ -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
@@ -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
 
@@ -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
- def self.version
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
 
@@ -166,7 +166,7 @@ module Sinatra
166
166
  alias member? has_key?
167
167
 
168
168
  def index(value)
169
- warn "Hash#index is deprecated; use Hash#key" if RUBY_VERSION > '1.9'
169
+ warn "Hash#index is deprecated; use Hash#key"
170
170
  key(value)
171
171
  end
172
172
 
@@ -90,7 +90,7 @@ module Sinatra
90
90
  link = (response["Link"] ||= "")
91
91
 
92
92
  urls.map do |url|
93
- link << "\n" unless link.empty?
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"].lines.map do |line|
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"
@@ -1,6 +1,6 @@
1
1
  require 'backports'
2
2
  require 'sinatra/base'
3
- require 'sinatra/decompile'
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
- # # The rest of your classic application code goes here...
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
- # # The rest of your modular application code goes here...
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", regexpify(@pattern), block)
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 || // unless a and b
250
- a, b = decompile(a), decompile(b) unless a.class == b.class
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
- def regexpify(pattern)
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 = '*' if method == :before or method == :after
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.extend_object(base)
356
+ def self.extended(base)
285
357
  base.extend BaseMethods
286
358
  end
287
359
  end