merb 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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)) }
|