merb 0.5.2 → 0.5.3
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.
- data/SVN_REVISION +1 -1
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +1 -1
- data/app_generators/merb/templates/script/destroy +1 -0
- data/app_generators/merb/templates/script/generate +4 -0
- data/lib/merb.rb +1 -0
- data/lib/merb/abstract_controller.rb +168 -55
- data/lib/merb/assets.rb +57 -16
- data/lib/merb/assets.rb.orig +119 -0
- data/lib/merb/boot_loader.rb +55 -4
- data/lib/merb/boot_loader.rb.orig +235 -0
- data/lib/merb/controller.rb +1 -1
- data/lib/merb/cookies.rb +95 -0
- data/lib/merb/mixins/controller.rb +1 -1
- data/lib/merb/mixins/render.rb +17 -4
- data/lib/merb/server.rb +23 -6
- data/lib/merb/test/helper.rb +6 -2
- data/lib/merb/version.rb +7 -4
- data/lib/tasks/merb.rake +1 -1
- data/spec/fixtures/controllers/render_spec_controllers.rb +10 -0
- data/spec/merb/controller_filters_spec.rb +1 -1
- data/spec/merb/cookie_store_spec.rb +1 -1
- data/spec/merb/cookies_spec.rb +96 -0
- data/spec/merb/render_spec.rb +17 -0
- metadata +7 -3
data/SVN_REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1334
|
@@ -131,7 +131,7 @@
|
|
131
131
|
<div class="header">
|
132
132
|
<h1><%= @exception.name.humanize %> <sup class="error_<%= @exception.class::STATUS %>"><%= @exception.class::STATUS %></sup></h1>
|
133
133
|
<% if show_details = ::Merb::Config[:exception_details] -%>
|
134
|
-
<h2
|
134
|
+
<h2><%== @exception.message %></h2>
|
135
135
|
<% else -%>
|
136
136
|
<h2>Sorry about that...</h2>
|
137
137
|
<% end -%>
|
data/lib/merb.rb
CHANGED
@@ -45,6 +45,7 @@ module Merb
|
|
45
45
|
autoload :Controller, 'merb/controller'
|
46
46
|
autoload :ControllerExceptions, 'merb/exceptions'
|
47
47
|
autoload :ControllerMixin, 'merb/mixins/controller'
|
48
|
+
autoload :Cookies, 'merb/cookies'
|
48
49
|
autoload :Dispatcher, 'merb/dispatcher'
|
49
50
|
autoload :DrbServiceProvider, 'drb_server'
|
50
51
|
autoload :ErubisCaptureMixin, 'merb/mixins/erubis_capture'
|
@@ -58,20 +58,27 @@ module Merb
|
|
58
58
|
end
|
59
59
|
|
60
60
|
|
61
|
-
# Adds a path to the template path cache.
|
61
|
+
# Adds the a template path to the template path cache. This is required for
|
62
62
|
# any view templates or layouts to be found during renering.
|
63
63
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
# ==== Parameters
|
65
|
+
# template_path<String>:: Full path to the template file.
|
66
|
+
#
|
67
|
+
# ==== Returns
|
68
|
+
# Boolean:: true unless the template path is less than three levels deep.
|
69
|
+
#
|
70
|
+
# ==== Examples
|
71
|
+
# Merb::AbstractController.add_path_to_template_cache('/full/path/to/template.html.erb')
|
72
|
+
#
|
73
|
+
def self.add_path_to_template_cache(template_path)
|
74
|
+
arry = template_path.split("/").last.split(".")
|
75
|
+
return false if template_path == "" || arry.size != 3
|
76
|
+
key = template_path.split(".")[0..-2].join(".")
|
77
|
+
self._template_path_cache[key] = template_path
|
72
78
|
end
|
73
79
|
|
74
80
|
# Resets the template_path_cache to an empty hash
|
81
|
+
#
|
75
82
|
def self.reset_template_path_cache!
|
76
83
|
self._template_path_cache = {}
|
77
84
|
end
|
@@ -88,7 +95,14 @@ module Merb
|
|
88
95
|
send(action, *args)
|
89
96
|
end
|
90
97
|
|
91
|
-
#
|
98
|
+
# Calls a filter chain according to rules.
|
99
|
+
#
|
100
|
+
# ==== Parameters
|
101
|
+
# filter_set<Array>:: Array of filter-rule pairs as two piece arrays.
|
102
|
+
#
|
103
|
+
# ==== Returns
|
104
|
+
# Symbol:: :filter_chain_completed to signify execution is completed.
|
105
|
+
#
|
92
106
|
def call_filters(filter_set)
|
93
107
|
(filter_set || []).each do |(filter, rule)|
|
94
108
|
ok = false
|
@@ -115,45 +129,38 @@ module Merb
|
|
115
129
|
return :filter_chain_completed
|
116
130
|
end
|
117
131
|
|
118
|
-
# +finalize_session+ is called at the end of a request to finalize/store
|
119
|
-
# Mixins/Classes wishing to define a new
|
120
|
-
# See merb/lib/sessions/*
|
121
|
-
|
132
|
+
# +finalize_session+ is called at the end of a request to finalize/store
|
133
|
+
# any data placed in the session. Mixins/Classes wishing to define a new
|
134
|
+
# session store must implement this method. See merb/lib/sessions/*
|
135
|
+
# for examples of built in session stores.
|
122
136
|
def finalize_session #:nodoc:
|
123
137
|
# noop
|
124
138
|
end
|
125
139
|
|
126
|
-
# +setup_session+ is called at the beginning of a request to load the
|
127
|
-
# Mixins/Classes wishing to define a new session
|
128
|
-
# See merb/lib/sessions/* for examples
|
129
|
-
|
140
|
+
# +setup_session+ is called at the beginning of a request to load the
|
141
|
+
# current session data. Mixins/Classes wishing to define a new session
|
142
|
+
# store must implement this method. See merb/lib/sessions/* for examples
|
143
|
+
# of built in session stores.
|
130
144
|
def setup_session #:nodoc:
|
131
145
|
# noop
|
132
146
|
end
|
133
147
|
|
134
|
-
#
|
148
|
+
# Override this method on your controller classes to specialize
|
135
149
|
# the output when the filter chain is halted.
|
150
|
+
#
|
151
|
+
# ==== Returns
|
152
|
+
# String:: A message explaining what happened.
|
153
|
+
#
|
136
154
|
def filters_halted
|
137
155
|
"<html><body><h1>Filter Chain Halted!</h1></body></html>"
|
138
156
|
end
|
139
157
|
|
140
158
|
|
141
|
-
#
|
142
|
-
#
|
143
|
-
# corresponds to a method name to call, or a proc object. if it is a method
|
144
|
-
# name that method will be called and if it is a proc it will be called
|
159
|
+
# Specify before filters in your controllers. If a method name is given
|
160
|
+
# that method will be called and if a proc is given it will be called
|
145
161
|
# with an argument of self where self is the current controller object.
|
146
162
|
# When you use a proc as a filter it needs to take one parameter.
|
147
163
|
#
|
148
|
-
# examples:
|
149
|
-
# before :some_filter
|
150
|
-
# before :authenticate, :exclude => [:login, :signup]
|
151
|
-
# before Proc.new {|c| c.some_method }, :only => :foo
|
152
|
-
#
|
153
|
-
# You can use either :only => :actionname or :exclude => [:this, :that]
|
154
|
-
# but not both at once. :only will only run before the listed actions
|
155
|
-
# and :exclude will run for every action that is not listed.
|
156
|
-
#
|
157
164
|
# Merb's before filter chain is very flexible. To halt the filter chain you
|
158
165
|
# use throw :halt. If throw is called with only one argument of :halt the
|
159
166
|
# return of the method filters_halted will be what is rendered to the view.
|
@@ -183,40 +190,86 @@ module Merb
|
|
183
190
|
#
|
184
191
|
# throw :halt, Proc.new {|c| c.access_denied }
|
185
192
|
# throw :halt, Proc.new {|c| Tidy.new(c.index) }
|
186
|
-
#
|
193
|
+
#
|
194
|
+
# ==== Parameters
|
195
|
+
# filter<Symbol, String, Proc>:: The filter to be added.
|
196
|
+
# opts<Hash>::
|
197
|
+
# The options for the filter to be added (see below). Defaults to an
|
198
|
+
# empty Hash.
|
199
|
+
#
|
200
|
+
# ==== Options (opts)
|
201
|
+
# :only<Array, Symbol>:: The actions that the filter should be applied to.
|
202
|
+
# :exclude<Array, Symbol>:: The actions that should ignore this filter.
|
203
|
+
#
|
204
|
+
# Note: :only and :exluce cannot be used simultaneously.
|
205
|
+
#
|
206
|
+
# ==== Examples
|
207
|
+
# before :some_filter
|
208
|
+
# before :authenticate, :exclude => [:login, :signup]
|
209
|
+
# before Proc.new {|c| c.some_method }, :only => :foo
|
210
|
+
#
|
187
211
|
def self.before(filter, opts={})
|
188
212
|
add_filter((self.before_filters ||= []), filter, opts)
|
189
213
|
end
|
190
214
|
|
191
|
-
#
|
192
|
-
#
|
193
|
-
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
#
|
197
|
-
#
|
198
|
-
|
215
|
+
# Specify after filters in your controllers. If a method name is given
|
216
|
+
# that method will be called and if a proc is given it will be called
|
217
|
+
# with an argument of self where self is the current controller object.
|
218
|
+
# When you use a proc as a filter it needs to take one parameter.
|
219
|
+
#
|
220
|
+
# ==== Parameters
|
221
|
+
# filter<Symbol, String, Proc>:: The filter to be added.
|
222
|
+
# opts<Hash>::
|
223
|
+
# The options for the filter to be added (see below). Defaults to an
|
224
|
+
# empty Hash.
|
225
|
+
#
|
226
|
+
# ==== Options (opts)
|
227
|
+
# :only<Array, Symbol>:: The actions that the filter should be applied to.
|
228
|
+
# :exclude<Array, Symbol>:: The actions that should ignore this filter.
|
229
|
+
#
|
230
|
+
# Note: :only and :exluce cannot be used simultaneously.
|
231
|
+
#
|
232
|
+
# ==== Examples
|
233
|
+
# after :some_filter
|
234
|
+
# after :tidy, :exclude => [:stats]
|
235
|
+
# before Proc.new {|c| c.some_method }, :only => :foo
|
236
|
+
#
|
199
237
|
def self.after(filter, opts={})
|
200
238
|
add_filter((self.after_filters ||= []), filter, opts)
|
201
239
|
end
|
202
240
|
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
241
|
+
# Remove an already declared before filter from your controller.
|
242
|
+
#
|
243
|
+
# ==== Parameters
|
244
|
+
# filter<String, Symbol>:: The filter to be removed.
|
245
|
+
#
|
246
|
+
# ==== Examples
|
206
247
|
# class Application < Merb::Controller
|
207
248
|
# before :require_login
|
208
249
|
# end
|
209
250
|
#
|
210
|
-
# class Login <
|
211
|
-
# skip_before :require_login #
|
251
|
+
# class Login < Application
|
252
|
+
# skip_before :require_login # Login should be accessible by everyone
|
212
253
|
# end
|
213
|
-
|
254
|
+
#
|
214
255
|
def self.skip_before(filter)
|
215
256
|
skip_filter((self.before_filters || []), filter)
|
216
257
|
end
|
217
258
|
|
218
|
-
#
|
219
|
-
|
259
|
+
# Remove an already declared after filter from your controller.
|
260
|
+
#
|
261
|
+
# ==== Parameters
|
262
|
+
# filter<String, Symbol>:: The filter to be removed.
|
263
|
+
#
|
264
|
+
# ==== Examples
|
265
|
+
# class Application < Merb::Controller
|
266
|
+
# after :log_activitiy
|
267
|
+
# end
|
268
|
+
#
|
269
|
+
# class Stats < Application
|
270
|
+
# skip_after :log_activitiy
|
271
|
+
# end
|
272
|
+
#
|
220
273
|
def self.skip_after(filter)
|
221
274
|
skip_filter((self.after_filters || []), filter)
|
222
275
|
end
|
@@ -225,17 +278,51 @@ module Merb
|
|
225
278
|
Hash.new{ |hash, key| hash[key] = "" }
|
226
279
|
end
|
227
280
|
|
228
|
-
# Set here to respond when rendering to cover the provides syntax of
|
281
|
+
# Set here to respond when rendering to cover the provides syntax of
|
282
|
+
# setting the content_type
|
283
|
+
#
|
284
|
+
# ==== Returns
|
285
|
+
# Boolean:: True if the content type was set.
|
286
|
+
#
|
229
287
|
def content_type_set?
|
230
288
|
false
|
231
289
|
end
|
232
290
|
|
291
|
+
# Returns the content type.
|
292
|
+
#
|
293
|
+
# ==== Returns
|
294
|
+
# Symbol:: The content type.
|
295
|
+
#
|
233
296
|
def content_type
|
234
297
|
params[:format] || :html
|
235
298
|
end
|
236
|
-
|
299
|
+
|
237
300
|
private
|
238
301
|
|
302
|
+
# Adds a filter to a list of filters.
|
303
|
+
#
|
304
|
+
# ==== Parameters
|
305
|
+
# filters<Array>::
|
306
|
+
# The array of filters to which the filter should be added.
|
307
|
+
# filter<Symbol, String, Proc>:: The filter to be added.
|
308
|
+
# opts<Hash>::
|
309
|
+
# The options for the filter to be added (see below). Defaults to an
|
310
|
+
# empty Hash.
|
311
|
+
#
|
312
|
+
# ==== Options (opts)
|
313
|
+
# :only<Array, Symbol>:: The actions that the filter should be applied to.
|
314
|
+
# :exclude<Array, Symbol>:: The actions that should ignore this filter.
|
315
|
+
#
|
316
|
+
# ==== Raises
|
317
|
+
# ArgumentError::
|
318
|
+
# The options include both the :only and the :exclude key or the filter
|
319
|
+
# is not a Symbol, String or Proc.
|
320
|
+
#
|
321
|
+
# ==== Examples
|
322
|
+
# add_filter([ :log_activity ], :login_required)
|
323
|
+
#
|
324
|
+
# add_filter([ :log_activity ], :login_required, { :exclude => :login })
|
325
|
+
#
|
239
326
|
def self.add_filter(filters, filter, opts={})
|
240
327
|
raise(ArgumentError,
|
241
328
|
"You can specify either :only or :exclude but
|
@@ -257,7 +344,20 @@ module Merb
|
|
257
344
|
)
|
258
345
|
end
|
259
346
|
end
|
260
|
-
|
347
|
+
|
348
|
+
# Removes a filter from a list of filters.
|
349
|
+
#
|
350
|
+
# ==== Parameters
|
351
|
+
# filters<Array>::
|
352
|
+
# The array of filters from which the filter should be removed.
|
353
|
+
# filter<Symbol, String>:: The filter to be removed.
|
354
|
+
#
|
355
|
+
# ==== Raises
|
356
|
+
# ArgumentError:: The filter argument is not a String or a Symbol.
|
357
|
+
#
|
358
|
+
# ==== Examples
|
359
|
+
# skip_filter([ :login_required, :log_activity ], :login_required)
|
360
|
+
#
|
261
361
|
def self.skip_filter(filters, filter)
|
262
362
|
raise(ArgumentError,
|
263
363
|
'You can only skip filters that have a String or Symbol name.'
|
@@ -267,10 +367,23 @@ module Merb
|
|
267
367
|
) unless filters.reject! {|f| f.first.to_s[filter.to_s] }
|
268
368
|
end
|
269
369
|
|
270
|
-
#
|
370
|
+
# Changes filter options hash values for the only and exclude keys to
|
371
|
+
# arrays, if they are not arrays already.
|
372
|
+
#
|
373
|
+
# ==== Parameters
|
374
|
+
# opts<Hash>:: The filter options hash. Will default to an empty Hash.
|
375
|
+
#
|
376
|
+
# ==== Options (opts)
|
377
|
+
# :only<Array, Symbol>:: The actions that the filter should be applied to.
|
378
|
+
# :exclude<Array, Symbol>:: The actions that should ignore this filter.
|
379
|
+
#
|
380
|
+
# ==== Returns
|
381
|
+
# Hash:: The original options with the only and exclude values as arrays.
|
382
|
+
#
|
383
|
+
# ==== Examples
|
384
|
+
# shuffle_filters!(:only => :new)
|
385
|
+
# # => { :only => [:new] }
|
271
386
|
#
|
272
|
-
# shuffle_filters!(:only => :new) #=> {:only => [:new]}
|
273
|
-
|
274
387
|
def self.shuffle_filters!(opts={})
|
275
388
|
if opts[:only] && opts[:only].is_a?(Symbol)
|
276
389
|
opts[:only] = [opts[:only]]
|
data/lib/merb/assets.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
module Merb
|
2
2
|
module Assets
|
3
3
|
|
4
|
-
#
|
5
|
-
#
|
4
|
+
# Check whether the assets should be bundled.
|
5
|
+
#
|
6
|
+
# ==== Returns
|
7
|
+
# Boolean::
|
8
|
+
# True if the assets should be bundled (e.g., production mode or
|
9
|
+
# :bundle_assets is explicitly enabled).
|
10
|
+
#
|
6
11
|
def self.bundle?
|
7
|
-
(Merb::Config[:environment] ==
|
12
|
+
(Merb::Config[:environment].to_s == 'production') ||
|
8
13
|
(!!Merb::Config[:bundle_assets])
|
9
14
|
end
|
10
15
|
|
@@ -20,8 +25,24 @@ module Merb
|
|
20
25
|
# true, returns the path relative to the Merb.root, not the public
|
21
26
|
# directory. Uses the path_prefix, if any is configured.
|
22
27
|
#
|
23
|
-
#
|
24
|
-
#
|
28
|
+
# ==== Parameters
|
29
|
+
# asset_type<Symbol>:: Type of the asset (e.g. :javascript).
|
30
|
+
# filename<~to_s>:: The path to the file.
|
31
|
+
#
|
32
|
+
# local_path<Boolean>::
|
33
|
+
# If true, the returned path will be relative to the Merb.root,
|
34
|
+
# otherwise it will be the public URI path. Defaults to false.
|
35
|
+
#
|
36
|
+
# ==== Returns
|
37
|
+
# String:: The path to the asset.
|
38
|
+
#
|
39
|
+
# ==== Examples
|
40
|
+
# asset_path(:javascript, :dingo)
|
41
|
+
# # => "/javascripts/dingo.js"
|
42
|
+
#
|
43
|
+
# asset_path(:javascript, :dingo, true)
|
44
|
+
# # => "public/javascripts/dingo.js"
|
45
|
+
#
|
25
46
|
def asset_path(asset_type, filename, local_path = false)
|
26
47
|
filename = filename.to_s
|
27
48
|
if filename !~ /#{'\\' + ASSET_FILE_EXTENSIONS[asset_type]}\Z/
|
@@ -40,24 +61,36 @@ module Merb
|
|
40
61
|
class AbstractAssetBundler
|
41
62
|
class << self
|
42
63
|
|
43
|
-
# Add a post-bundle callback
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# end
|
64
|
+
# Add a post-bundle callback.
|
65
|
+
#
|
66
|
+
# ==== Examples
|
67
|
+
# add_callback { |filename| `yuicompressor #{filename}` }
|
68
|
+
#
|
49
69
|
def add_callback(&block)
|
50
70
|
callbacks << block
|
51
71
|
end
|
52
72
|
alias_method :after_bundling, :add_callback
|
53
73
|
|
54
|
-
#
|
74
|
+
# Retrieve existing callbacks.
|
75
|
+
#
|
76
|
+
# ==== Returns
|
77
|
+
# Array:: An array of existing callbacks.
|
78
|
+
#
|
55
79
|
def callbacks
|
56
80
|
@callbacks ||= []
|
57
81
|
return @callbacks
|
58
82
|
end
|
59
83
|
|
60
|
-
# The type of asset for which the bundler is responsible.
|
84
|
+
# The type of asset for which the bundler is responsible. Override
|
85
|
+
# this method in your bundler code.
|
86
|
+
#
|
87
|
+
# ==== Raises
|
88
|
+
# NotImplementedError::
|
89
|
+
# If this method has not been implemented by the bundler.
|
90
|
+
#
|
91
|
+
# ==== Returns
|
92
|
+
# Symbol:: The type of the asset
|
93
|
+
#
|
61
94
|
def asset_type
|
62
95
|
raise NotImplementedError, "should return a symbol for the first argument to be passed to asset_path"
|
63
96
|
end
|
@@ -73,8 +106,11 @@ module Merb
|
|
73
106
|
@files = files.map { |f| asset_path(self.class.asset_type, f, true) }
|
74
107
|
end
|
75
108
|
|
76
|
-
# Creates the new bundled file,
|
77
|
-
#
|
109
|
+
# Creates the new bundled file, executing all the callbacks.
|
110
|
+
#
|
111
|
+
# ==== Returns
|
112
|
+
# Symbol:: Name of the bundle.
|
113
|
+
#
|
78
114
|
def bundle!
|
79
115
|
# TODO: Move this file check out into an in-memory cache. Also, push it out to the helper level so we don't have to create the helper object.
|
80
116
|
unless File.exist?(@bundle_filename)
|
@@ -88,7 +124,12 @@ module Merb
|
|
88
124
|
|
89
125
|
include Merb::Assets::AssetHelpers # for asset_path
|
90
126
|
|
91
|
-
# Bundle all the
|
127
|
+
# Bundle all the files into one.
|
128
|
+
#
|
129
|
+
# ==== Parameters
|
130
|
+
# filename<String>:: Name of the bundle file.
|
131
|
+
# files<Array>:: An array of filenames to be bundled.
|
132
|
+
#
|
92
133
|
def bundle_files(filename, *files)
|
93
134
|
File.open(filename, "w") do |f|
|
94
135
|
files.each { |file| f.puts(File.read(file)) }
|