merb-core 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +22 -13
- data/lib/merb-core/bootloader.rb +3 -2
- data/lib/merb-core/config.rb +1 -1
- data/lib/merb-core/constants.rb +3 -1
- data/lib/merb-core/controller/abstract_controller.rb +25 -39
- data/lib/merb-core/controller/exceptions.rb +14 -16
- data/lib/merb-core/controller/merb_controller.rb +2 -2
- data/lib/merb-core/controller/mime.rb +2 -1
- data/lib/merb-core/controller/mixins/render.rb +12 -0
- data/lib/merb-core/controller/mixins/responder.rb +31 -7
- data/lib/merb-core/core_ext/hash.rb +7 -0
- data/lib/merb-core/core_ext/kernel.rb +31 -34
- data/lib/merb-core/core_ext.rb +1 -0
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +3 -3
- data/lib/merb-core/dispatch/dispatcher.rb +128 -135
- data/lib/merb-core/dispatch/request.rb +11 -11
- data/lib/merb-core/dispatch/router/behavior.rb +6 -6
- data/lib/merb-core/dispatch/router.rb +5 -5
- data/lib/merb-core/logger.rb +203 -202
- data/lib/merb-core/rack/application.rb +19 -5
- data/lib/merb-core/rack/middleware/conditional_get.rb +23 -0
- data/lib/merb-core/rack/middleware/content_length.rb +18 -0
- data/lib/merb-core/rack/middleware/tracer.rb +20 -0
- data/lib/merb-core/rack/middleware.rb +1 -7
- data/lib/merb-core/rack.rb +19 -16
- data/lib/merb-core/test/matchers/route_matchers.rb +1 -0
- data/lib/merb-core/test/matchers/view_matchers.rb +36 -0
- data/lib/merb-core/test/run_specs.rb +2 -1
- data/lib/merb-core/version.rb +1 -1
- data/lib/merb-core.rb +39 -33
- data/spec/private/config/merb_spec.rb +34 -0
- data/spec/private/dispatch/fixture/log/merb_test.log +372 -0
- data/spec/private/router/fixture/log/merb_test.log +42 -0
- data/spec/public/abstract_controller/controllers/filters.rb +50 -1
- data/spec/public/abstract_controller/filter_spec.rb +25 -0
- data/spec/public/controller/base_spec.rb +41 -1
- data/spec/public/controller/controllers/base.rb +16 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -1
- data/spec/public/controller/dispatcher_spec.rb +24 -25
- data/spec/public/controller/responder_spec.rb +6 -0
- data/spec/public/core_ext/kernel_spec.rb +79 -0
- data/spec/public/directory_structure/directory/log/merb_test.log +245 -0
- data/spec/public/rack/conditinal_get_middleware_spec.rb +139 -0
- data/spec/public/rack/rack_middleware_spec.rb +99 -0
- data/spec/public/rack/shared_example_groups.rb +35 -0
- data/spec/public/reloading/directory/log/merb_test.log +40 -0
- data/spec/public/request/request_spec.rb +0 -5
- data/spec/public/router/fixture/log/merb_test.log +348 -0
- data/spec/public/test/route_matchers_spec.rb +4 -0
- data/spec/spec_helper.rb +7 -1
- metadata +42 -5
- data/spec/private/plugins/plugin_spec.rb +0 -166
data/Rakefile
CHANGED
@@ -59,13 +59,16 @@ spec = Gem::Specification.new do |s|
|
|
59
59
|
#s.rdoc_options += RDOC_OPTS + ["--exclude", "^(app|uploads)"]
|
60
60
|
|
61
61
|
# Dependencies
|
62
|
-
s.add_dependency "extlib", ">=0.9.
|
62
|
+
s.add_dependency "extlib", ">=0.9.4"
|
63
63
|
s.add_dependency "erubis"
|
64
64
|
s.add_dependency "rake"
|
65
65
|
s.add_dependency "json_pure"
|
66
66
|
s.add_dependency "rspec"
|
67
67
|
s.add_dependency "rack"
|
68
68
|
s.add_dependency "mime-types"
|
69
|
+
s.add_dependency "hpricot"
|
70
|
+
s.add_development_dependency "libxml-ruby"
|
71
|
+
s.add_development_dependency "memcache-client"
|
69
72
|
# Requirements
|
70
73
|
s.requirements << "install the json gem to get faster json parsing"
|
71
74
|
s.required_ruby_version = ">= 1.8.6"
|
@@ -80,6 +83,11 @@ task :install => :package do
|
|
80
83
|
sh %{#{sudo} gem install #{install_home} --local pkg/#{GEM_NAME}-#{GEM_VERSION}.gem --no-rdoc --no-ri}
|
81
84
|
end
|
82
85
|
|
86
|
+
desc "Install Merb with development dependencies"
|
87
|
+
task :dev_install => :package do
|
88
|
+
sh %{#{sudo} gem install #{install_home} --local pkg/#{GEM_NAME}-#{GEM_VERSION}.gem --no-rdoc --no-ri --development}
|
89
|
+
end
|
90
|
+
|
83
91
|
desc "Run :package and install the resulting .gem with jruby"
|
84
92
|
task :jinstall => :package do
|
85
93
|
sh %{#{sudo} jruby -S gem install #{install_home} pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
|
@@ -176,7 +184,7 @@ task :aok => [:specs, :rcov]
|
|
176
184
|
# t.spec_files = Dir["spec/**/*_spec.rb"].sort
|
177
185
|
# end
|
178
186
|
|
179
|
-
def setup_specs(name, spec_cmd='spec', run_opts = "-c
|
187
|
+
def setup_specs(name, spec_cmd='spec', run_opts = "-c")
|
180
188
|
desc "Run all specs (#{name})"
|
181
189
|
task "specs:#{name}" do
|
182
190
|
run_specs("spec/**/*_spec.rb", spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
|
@@ -212,9 +220,9 @@ end
|
|
212
220
|
setup_specs("mri", "spec")
|
213
221
|
setup_specs("jruby", "jruby -S spec")
|
214
222
|
|
215
|
-
task "specs" => ["specs:mri"]
|
216
|
-
task "specs:private" => ["specs:mri:private"]
|
217
|
-
task "specs:public" => ["specs:mri:public"]
|
223
|
+
task "specs" => ["dev_install", "specs:mri"]
|
224
|
+
task "specs:private" => ["dev_install", "specs:mri:private"]
|
225
|
+
task "specs:public" => ["dev_install", "specs:mri:public"]
|
218
226
|
|
219
227
|
desc "Run coverage suite"
|
220
228
|
task :rcov do
|
@@ -233,7 +241,7 @@ end
|
|
233
241
|
|
234
242
|
desc "Run a specific spec with TASK=xxxx"
|
235
243
|
Spec::Rake::SpecTask.new("spec") do |t|
|
236
|
-
t.spec_opts = ["--
|
244
|
+
t.spec_opts = ["--colour"]
|
237
245
|
t.libs = ["lib", "server/lib" ]
|
238
246
|
t.spec_files = (ENV["TASK"] || '').split(',').map do |task|
|
239
247
|
"spec/**/#{task}_spec.rb"
|
@@ -313,9 +321,10 @@ namespace :repo do
|
|
313
321
|
|
314
322
|
end
|
315
323
|
|
316
|
-
def git_log(since_release = nil, log_format = "
|
317
|
-
git_log_query = "git log
|
318
|
-
git_log_query << "
|
324
|
+
def git_log(since_release = nil, log_format = "%an")
|
325
|
+
git_log_query = "git log"
|
326
|
+
git_log_query << " v#{since_release}..HEAD" if since_release
|
327
|
+
git_log_query << " --pretty='format:#{log_format}' --no-merges"
|
319
328
|
puts
|
320
329
|
puts "Running #{git_log_query}"
|
321
330
|
puts
|
@@ -323,10 +332,10 @@ def git_log(since_release = nil, log_format = "format:%an")
|
|
323
332
|
end
|
324
333
|
|
325
334
|
def contributors(since_release = nil)
|
326
|
-
|
335
|
+
git_log(since_release).split("\n").uniq.sort
|
327
336
|
end
|
328
337
|
|
329
|
-
PREVIOUS_RELEASE = '0.9.
|
338
|
+
PREVIOUS_RELEASE = '0.9.4'
|
330
339
|
namespace :history do
|
331
340
|
namespace :update do
|
332
341
|
desc "updates contributors list"
|
@@ -360,7 +369,7 @@ namespace :history do
|
|
360
369
|
namespace :current_release do
|
361
370
|
desc "show changes since previous release"
|
362
371
|
task :changes do
|
363
|
-
puts git_log(PREVIOUS_RELEASE, "
|
372
|
+
puts git_log(PREVIOUS_RELEASE, "* %s")
|
364
373
|
end
|
365
374
|
|
366
375
|
|
@@ -399,7 +408,7 @@ rule "" do |t|
|
|
399
408
|
|
400
409
|
example = " -e '#{spec_name}'" unless spec_name.empty?
|
401
410
|
|
402
|
-
sh "#{spec_cmd} #{run_file_name} --
|
411
|
+
sh "#{spec_cmd} #{run_file_name} --colour #{example}"
|
403
412
|
end
|
404
413
|
end
|
405
414
|
|
data/lib/merb-core/bootloader.rb
CHANGED
@@ -542,7 +542,7 @@ class Merb::BootLoader::MimeTypes < Merb::BootLoader
|
|
542
542
|
Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml], :charset => "utf-8")
|
543
543
|
Merb.add_mime_type(:text, :to_text, %w[text/plain], :charset => "utf-8")
|
544
544
|
Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html], :charset => "utf-8")
|
545
|
-
Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :charset => "utf-8")
|
545
|
+
Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], {:charset => "utf-8"}, 0.9998)
|
546
546
|
Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript], :charset => "utf-8")
|
547
547
|
Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json], :charset => "utf-8")
|
548
548
|
end
|
@@ -673,6 +673,7 @@ class Merb::BootLoader::RackUpApplication < Merb::BootLoader
|
|
673
673
|
run Merb::Rack::Application.new
|
674
674
|
}.to_app
|
675
675
|
end
|
676
|
+
|
676
677
|
end
|
677
678
|
end
|
678
679
|
|
@@ -727,4 +728,4 @@ class Merb::BootLoader::ReloadTemplates < Merb::BootLoader
|
|
727
728
|
Merb::Config[:reload_templates] = (Merb.environment == "development")
|
728
729
|
end
|
729
730
|
end
|
730
|
-
end
|
731
|
+
end
|
data/lib/merb-core/config.rb
CHANGED
data/lib/merb-core/constants.rb
CHANGED
@@ -23,6 +23,8 @@ module Merb
|
|
23
23
|
FORM_URL_ENCODED_REGEXP = %r{^application/x-www-form-urlencoded}.freeze
|
24
24
|
UPCASE_CONTENT_TYPE = 'CONTENT_TYPE'.freeze
|
25
25
|
CONTENT_TYPE = "Content-Type".freeze
|
26
|
+
DATE = 'Date'.freeze
|
27
|
+
ETAG = 'ETag'.freeze
|
26
28
|
LAST_MODIFIED = "Last-Modified".freeze
|
27
29
|
SLASH = "/".freeze
|
28
30
|
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
@@ -40,4 +42,4 @@ module Merb
|
|
40
42
|
REQUEST_PATH = "REQUEST_PATH".freeze
|
41
43
|
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
42
44
|
end
|
43
|
-
end
|
45
|
+
end
|
@@ -26,38 +26,41 @@
|
|
26
26
|
# ===== Examples
|
27
27
|
# before :some_filter
|
28
28
|
# before :authenticate, :exclude => [:login, :signup]
|
29
|
-
# before :has_role, :with => ["Admin"], :exclude => [:index
|
29
|
+
# before :has_role, :with => ["Admin"], :exclude => [:index, :show]
|
30
30
|
# before Proc.new {|c| c.some_method }, :only => :foo
|
31
|
-
# before :authorize, :unless => logged_in?
|
31
|
+
# before :authorize, :unless => :logged_in?
|
32
32
|
#
|
33
|
-
# You can use either
|
34
|
-
# but not both at once.
|
35
|
-
#
|
33
|
+
# You can use either <code>:only => :actionname</code> or
|
34
|
+
# <code>:exclude => [:this, :that]</code> but not both at once.
|
35
|
+
# <code>:only</code> will only run before the listed actions and
|
36
|
+
# <code>:exclude</code> will run for every action that is not listed.
|
36
37
|
#
|
37
38
|
# Merb's before filter chain is very flexible. To halt the filter chain you
|
38
|
-
# use throw :halt
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
39
|
+
# use <code>throw :halt</code>. If <code>throw</code> is called with only one
|
40
|
+
# argument of <code>:halt</code> the return value of the method
|
41
|
+
# <code>filters_halted</code> will be what is rendered to the view. You can
|
42
|
+
# override <code>filters_halted</code> in your own controllers to control what
|
43
|
+
# it outputs. But the <code>throw</code> construct is much more powerful than
|
44
|
+
# just that.
|
45
|
+
#
|
46
|
+
# <code>throw :halt</code> can also take a second argument. Here is what that
|
47
|
+
# second argument can be and the behavior each type can have:
|
44
48
|
#
|
45
49
|
# * +String+:
|
46
|
-
# when the second
|
47
|
-
# is rendered to the browser. Since merb's render method returns
|
50
|
+
# when the second argument is a string then that string will be what
|
51
|
+
# is rendered to the browser. Since merb's <code>#render</code> method returns
|
48
52
|
# a string you can render a template or just use a plain string:
|
49
53
|
#
|
50
54
|
# throw :halt, "You don't have permissions to do that!"
|
51
55
|
# throw :halt, render(:action => :access_denied)
|
52
56
|
#
|
53
57
|
# * +Symbol+:
|
54
|
-
# If the second arg is a symbol then the method named after that
|
58
|
+
# If the second arg is a symbol, then the method named after that
|
55
59
|
# symbol will be called
|
56
60
|
#
|
57
|
-
#
|
61
|
+
# throw :halt, :must_click_disclaimer
|
58
62
|
#
|
59
63
|
# * +Proc+:
|
60
|
-
#
|
61
64
|
# If the second arg is a Proc, it will be called and its return
|
62
65
|
# value will be what is rendered to the browser:
|
63
66
|
#
|
@@ -86,9 +89,9 @@
|
|
86
89
|
# Filter:: <Array[Symbol, (Symbol, String, Proc)]>
|
87
90
|
#
|
88
91
|
# ==== params[:action] and params[:controller] deprecated
|
89
|
-
# params[:action] and params[:controller] have been deprecated as of
|
92
|
+
# <code>params[:action]</code> and <code>params[:controller]</code> have been deprecated as of
|
90
93
|
# the 0.9.0 release. They are no longer set during dispatch, and
|
91
|
-
# have been replaced by action_name and controller_name respectively.
|
94
|
+
# have been replaced by <code>action_name</code> and <code>controller_name</code> respectively.
|
92
95
|
class Merb::AbstractController
|
93
96
|
include Merb::RenderMixin
|
94
97
|
include Merb::InlineTemplates
|
@@ -96,7 +99,7 @@ class Merb::AbstractController
|
|
96
99
|
class_inheritable_accessor :_layout, :_template_root, :template_roots
|
97
100
|
class_inheritable_accessor :_before_filters, :_after_filters
|
98
101
|
|
99
|
-
cattr_accessor :_abstract_subclasses
|
102
|
+
cattr_accessor :_abstract_subclasses
|
100
103
|
|
101
104
|
#---
|
102
105
|
# @semipublic
|
@@ -157,7 +160,7 @@ class Merb::AbstractController
|
|
157
160
|
# of controller/action.mime.type
|
158
161
|
#---
|
159
162
|
# @public
|
160
|
-
def _template_location(context, type
|
163
|
+
def _template_location(context, type, controller)
|
161
164
|
controller ? "#{controller}/#{context}" : context
|
162
165
|
end
|
163
166
|
|
@@ -234,7 +237,7 @@ class Merb::AbstractController
|
|
234
237
|
#
|
235
238
|
# ==== Raises
|
236
239
|
# MerbControllerError:: Invalid body content caught.
|
237
|
-
def _dispatch(action
|
240
|
+
def _dispatch(action)
|
238
241
|
setup_session
|
239
242
|
self.action_name = action
|
240
243
|
|
@@ -252,7 +255,7 @@ class Merb::AbstractController
|
|
252
255
|
when Symbol then __send__(caught)
|
253
256
|
when Proc then caught.call(self)
|
254
257
|
else
|
255
|
-
raise
|
258
|
+
raise ArgumentError, "Threw :halt, #{caught}. Expected String, nil, Symbol, Proc."
|
256
259
|
end
|
257
260
|
start = Time.now
|
258
261
|
_call_filters(_after_filters)
|
@@ -417,23 +420,6 @@ class Merb::AbstractController
|
|
417
420
|
# Method stub for finalizing up the session. This will be overriden by
|
418
421
|
# session modules.
|
419
422
|
def finalize_session() end
|
420
|
-
|
421
|
-
# Handles the template cache (which is used by BootLoader to cache the list
|
422
|
-
# of all templates).
|
423
|
-
#
|
424
|
-
# ==== Parameters
|
425
|
-
# template<String>::
|
426
|
-
# The full path to a template to add to the list of available templates
|
427
|
-
def self.add_path_to_template_cache(template)
|
428
|
-
return false if template.blank? || template.split("/").last.split(".").size != 3
|
429
|
-
key = template.match(/(.*)\.(.*)$/)[1]
|
430
|
-
self._template_path_cache[key] = template
|
431
|
-
end
|
432
|
-
|
433
|
-
# Resets the template_path_cache to an empty hash
|
434
|
-
def self.reset_template_path_cache!
|
435
|
-
self._template_path_cache = {}
|
436
|
-
end
|
437
423
|
|
438
424
|
# ==== Parameters
|
439
425
|
# name<~to_sym, Hash>:: The name of the URL to generate.
|
@@ -24,14 +24,14 @@ end
|
|
24
24
|
|
25
25
|
module Merb
|
26
26
|
# ControllerExceptions are a way of simplifying controller code by placing
|
27
|
-
#
|
27
|
+
# exception logic back into the MVC pattern.
|
28
28
|
#
|
29
29
|
# When a ControllerException is raised within your application merb will
|
30
30
|
# attempt to re-route the request to your Exceptions controller to render
|
31
|
-
# the error in a friendly
|
31
|
+
# the error in a friendly manor.
|
32
32
|
#
|
33
33
|
# For example you might have an action in your app that raises NotFound
|
34
|
-
# if a
|
34
|
+
# if a resource was not available
|
35
35
|
#
|
36
36
|
|
37
37
|
# def show
|
@@ -41,7 +41,7 @@ module Merb
|
|
41
41
|
# end
|
42
42
|
#
|
43
43
|
# This would halt execution of your action and re-route it over to your
|
44
|
-
# Exceptions controller which might look something like
|
44
|
+
# Exceptions controller which might look something like:
|
45
45
|
#
|
46
46
|
# class Exceptions < Application
|
47
47
|
|
@@ -50,16 +50,16 @@ module Merb
|
|
50
50
|
# end
|
51
51
|
# end
|
52
52
|
#
|
53
|
-
# As usual the not_found action will look for a template in
|
53
|
+
# As usual, the not_found action will look for a template in
|
54
54
|
# app/views/exceptions/not_found.html.erb
|
55
55
|
#
|
56
56
|
# Note: All standard ControllerExceptions have an HTTP status code associated
|
57
|
-
# with them which is sent to the browser when the action
|
57
|
+
# with them which is sent to the browser when the action is rendered.
|
58
58
|
#
|
59
59
|
# Note: If you do not specifiy how to handle raised ControllerExceptions
|
60
60
|
# or an unhandlable exception occurs within your customised exception action
|
61
|
-
# then they will be rendered using the built-in error template
|
62
|
-
#
|
61
|
+
# then they will be rendered using the built-in error template.
|
62
|
+
# In development mode this "built in" template will show stack-traces for
|
63
63
|
# any of the ServerError family of exceptions (you can force the stack-trace
|
64
64
|
# to display in production mode using the :exception_details config option in
|
65
65
|
# merb.yml)
|
@@ -68,13 +68,13 @@ module Merb
|
|
68
68
|
# ==== Internal Exceptions
|
69
69
|
#
|
70
70
|
# Any other rogue errors (not ControllerExceptions) that occur during the
|
71
|
-
# execution of
|
72
|
-
# InternalServerError
|
73
|
-
# on your Exceptions controller.
|
71
|
+
# execution of your app will be converted into the ControllerException
|
72
|
+
# InternalServerError. And like all other exceptions, the ControllerExceptions
|
73
|
+
# can be caught on your Exceptions controller.
|
74
74
|
#
|
75
|
-
# InternalServerErrors return status 500, a common use for
|
75
|
+
# InternalServerErrors return status 500, a common use for customizing this
|
76
76
|
# action might be to send emails to the development team, warning that their
|
77
|
-
# application
|
77
|
+
# application has exploded. Mock example:
|
78
78
|
#
|
79
79
|
|
80
80
|
# def internal_server_error
|
@@ -82,7 +82,7 @@ module Merb
|
|
82
82
|
# "team@cowboys.com",
|
83
83
|
# "Exception occured at #{Time.now}",
|
84
84
|
# params[:exception])
|
85
|
-
# render 'Something is wrong, but the team
|
85
|
+
# render 'Something is wrong, but the team is on it!'
|
86
86
|
# end
|
87
87
|
#
|
88
88
|
# Note: The special param[:exception] is available in all Exception actions
|
@@ -290,10 +290,8 @@ module Merb
|
|
290
290
|
|
291
291
|
class InternalServerError < Merb::ControllerExceptions::ServerError #:doc:
|
292
292
|
self.status = 500;
|
293
|
-
# DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
|
294
293
|
def initialize(exception = nil)
|
295
294
|
@exception = exception
|
296
|
-
@coderay = CodeRay rescue nil
|
297
295
|
end
|
298
296
|
|
299
297
|
def backtrace
|
@@ -137,7 +137,7 @@ class Merb::Controller < Merb::AbstractController
|
|
137
137
|
#
|
138
138
|
#---
|
139
139
|
# @public
|
140
|
-
def _template_location(context, type
|
140
|
+
def _template_location(context, type, controller)
|
141
141
|
_conditionally_append_extension(controller ? "#{controller}/#{context}" : "#{context}", type)
|
142
142
|
end
|
143
143
|
|
@@ -256,7 +256,7 @@ class Merb::Controller < Merb::AbstractController
|
|
256
256
|
private
|
257
257
|
|
258
258
|
# If not already added, add the proper mime extension to the template path.
|
259
|
-
def _conditionally_append_extension(template, type
|
259
|
+
def _conditionally_append_extension(template, type)
|
260
260
|
type && !template.match(/\.#{type.to_s.escape_regexp}$/) ? "#{template}.#{type}" : template
|
261
261
|
end
|
262
262
|
|
@@ -38,7 +38,7 @@ module Merb
|
|
38
38
|
# correctly appended to the mimetype itself.
|
39
39
|
# &block:: a block which recieves the current controller when the format
|
40
40
|
# is set (in the controller's #content_type method)
|
41
|
-
def add_mime_type(key, transform_method, mimes, new_response_headers = {}, &block)
|
41
|
+
def add_mime_type(key, transform_method, mimes, new_response_headers = {}, default_quality = 1, &block)
|
42
42
|
enforce!(key => Symbol, mimes => Array)
|
43
43
|
|
44
44
|
content_type = new_response_headers["Content-Type"] || mimes.first
|
@@ -52,6 +52,7 @@ module Merb
|
|
52
52
|
:transform_method => transform_method,
|
53
53
|
:content_type => content_type,
|
54
54
|
:response_headers => new_response_headers,
|
55
|
+
:default_quality => default_quality,
|
55
56
|
:response_block => block })
|
56
57
|
|
57
58
|
mimes.each do |mime|
|
@@ -478,4 +478,16 @@ module Merb::RenderMixin
|
|
478
478
|
@_caught_content[obj] << string.to_s << (block_given? ? capture(&block) : "")
|
479
479
|
end
|
480
480
|
|
481
|
+
# Called when renderers need to be sure that existing thrown content is cleared
|
482
|
+
# before throwing new content. This prevents double rendering of content when
|
483
|
+
# multiple templates are rendered after each other.
|
484
|
+
#
|
485
|
+
# ==== Parameters
|
486
|
+
# obj<Object>:: The key in the thrown_content hash. Defaults to :for_layout.
|
487
|
+
#---
|
488
|
+
# @public
|
489
|
+
def clear_content(obj = :for_layout)
|
490
|
+
@_caught_content.delete(obj) unless @_caught_content[obj].nil?
|
491
|
+
end
|
492
|
+
|
481
493
|
end
|
@@ -352,6 +352,30 @@ module Merb
|
|
352
352
|
|
353
353
|
class Responder
|
354
354
|
|
355
|
+
# def self.parse(accept_header)
|
356
|
+
# headers = accept_header.split(/,/)
|
357
|
+
#
|
358
|
+
# ret = {}
|
359
|
+
# headers.each do |header|
|
360
|
+
# header =~ /\s*([^;\s]*)\s*(;\s*q=\s*([\d\.]+))?/
|
361
|
+
# quality = $3.to_f || 0 if $1 == "*/*"
|
362
|
+
# quality = quality ? quality.to_f : 1
|
363
|
+
# mime = mime(range)
|
364
|
+
# ret[mime] = [mime_name(range), quality * mime[:default_quality]]
|
365
|
+
# end
|
366
|
+
# ret.sort_by {|k,v| [v.last]}
|
367
|
+
# end
|
368
|
+
#
|
369
|
+
# def self.mime_name(range)
|
370
|
+
# @mime_names ||= {}
|
371
|
+
# @mime_names[range] ||= Merb::ResponderMixin::MIMES[@media_range]
|
372
|
+
# end
|
373
|
+
#
|
374
|
+
# def self.mime(range)
|
375
|
+
# @mime ||= {}
|
376
|
+
# @mime[range] ||= Merb.available_mime_types[mime_name(range)]
|
377
|
+
# end
|
378
|
+
|
355
379
|
protected
|
356
380
|
|
357
381
|
# Parses the raw accept header into an array of sorted AcceptType objects.
|
@@ -362,11 +386,6 @@ module Merb
|
|
362
386
|
# ==== Returns
|
363
387
|
# Array[AcceptType]:: The accepted types.
|
364
388
|
def self.parse(accept_header)
|
365
|
-
# FF2 is broken. If we get FF2 headers, use FF3 headers instead.
|
366
|
-
if accept_header == "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
|
367
|
-
accept_header = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
368
|
-
end
|
369
|
-
|
370
389
|
headers = accept_header.split(/,/)
|
371
390
|
idx, list = 0, []
|
372
391
|
while idx < headers.size
|
@@ -396,6 +415,7 @@ module Merb
|
|
396
415
|
@type, @sub_type = @media_range.split(%r{/})
|
397
416
|
(quality ||= 0.0) if @media_range == "*/*"
|
398
417
|
@quality = quality ? (quality.to_f * 100).to_i : 100
|
418
|
+
@quality *= (mime && mime[:default_quality] || 1)
|
399
419
|
end
|
400
420
|
|
401
421
|
# Compares two accept types for sorting purposes.
|
@@ -439,12 +459,16 @@ module Merb
|
|
439
459
|
# All Accept header values, such as "text/html", that match this type.
|
440
460
|
def synonyms
|
441
461
|
return @syns if @syns
|
442
|
-
if
|
443
|
-
@syns =
|
462
|
+
if _mime = mime
|
463
|
+
@syns = _mime[:accepts]
|
444
464
|
else
|
445
465
|
@syns = []
|
446
466
|
end
|
447
467
|
end
|
468
|
+
|
469
|
+
def mime
|
470
|
+
@mime ||= Merb.available_mime_types[Merb::ResponderMixin::MIMES[@media_range]]
|
471
|
+
end
|
448
472
|
|
449
473
|
# ==== Returns
|
450
474
|
# String::
|
@@ -113,7 +113,7 @@ module Kernel
|
|
113
113
|
# Mapper) you wish to use. Currently Merb has plugins to support
|
114
114
|
# ActiveRecord, DataMapper, and Sequel.
|
115
115
|
#
|
116
|
-
# @param orm
|
116
|
+
# @param orm<Symbol> The ORM to use.
|
117
117
|
#
|
118
118
|
# @example
|
119
119
|
# use_orm :datamapper
|
@@ -124,9 +124,10 @@ module Kernel
|
|
124
124
|
# @note
|
125
125
|
# If for some reason this is called more than once, latter
|
126
126
|
# call takes over other.
|
127
|
+
# @api public
|
127
128
|
def use_orm(orm)
|
128
129
|
begin
|
129
|
-
|
130
|
+
Merb.orm = orm
|
130
131
|
orm_plugin = "merb_#{orm}"
|
131
132
|
Kernel.dependency(orm_plugin)
|
132
133
|
rescue LoadError => e
|
@@ -135,17 +136,6 @@ module Kernel
|
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
138
|
-
|
139
|
-
# Registers ORM at generator scope.
|
140
|
-
#
|
141
|
-
# @param orm<#to_sym>
|
142
|
-
# ORM alias, like :activerecord, :datamapper or :sequel.
|
143
|
-
#
|
144
|
-
# @api private
|
145
|
-
def register_orm(orm)
|
146
|
-
Merb.orm_generator_scope = orm
|
147
|
-
end
|
148
|
-
|
149
139
|
# Used in Merb.root/config/init.rb to tell Merb which testing framework to
|
150
140
|
# use. Currently Merb has plugins to support RSpec and Test::Unit.
|
151
141
|
#
|
@@ -157,32 +147,39 @@ module Kernel
|
|
157
147
|
#
|
158
148
|
# # This will now use the RSpec generator for tests
|
159
149
|
# $ merb-gen model ActivityEvent
|
150
|
+
# @api public
|
160
151
|
def use_test(test_framework, *test_dependencies)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
dependencies test_dependencies if Merb.env == "test" || Merb.env.nil?
|
152
|
+
Merb.test_framework = test_framework
|
153
|
+
|
154
|
+
Kernel.dependencies test_dependencies if Merb.env == "test" || Merb.env.nil?
|
165
155
|
end
|
166
|
-
|
167
|
-
#
|
156
|
+
|
157
|
+
# Used in Merb.root/config/init.rb to tell Merb which template engine to
|
158
|
+
# prefer.
|
168
159
|
#
|
169
|
-
# @param
|
170
|
-
# The
|
160
|
+
# @param template_engine<Symbol>
|
161
|
+
# The template engine to use.
|
171
162
|
#
|
172
|
-
# @
|
173
|
-
|
174
|
-
[:rspec, :test_unit].include?(test_framework.to_sym)
|
175
|
-
end
|
176
|
-
|
177
|
-
# Register test framework at generator scope. Currently Merb has plugins to support RSpec and Test::Unit.
|
178
|
-
#
|
179
|
-
# @param test_framework<Symbol>
|
180
|
-
# The test framework to check. Currently only supports :rspec and :test_unit but the
|
181
|
-
# check is performed before registration if you use API.
|
163
|
+
# @example
|
164
|
+
# use_template_engine :haml
|
182
165
|
#
|
183
|
-
#
|
184
|
-
|
185
|
-
|
166
|
+
# # This will now use haml templates in generators where available.
|
167
|
+
# $ merb-gen resource_controller Project
|
168
|
+
# @api public
|
169
|
+
def use_template_engine(template_engine)
|
170
|
+
Merb.template_engine = template_engine
|
171
|
+
|
172
|
+
if template_engine != :erb
|
173
|
+
if template_engine.in?(:haml, :builder)
|
174
|
+
template_engine_plugin = "merb-#{template_engine}"
|
175
|
+
else
|
176
|
+
template_engine_plugin = "merb_#{template_engine}"
|
177
|
+
end
|
178
|
+
Kernel.dependency(template_engine_plugin)
|
179
|
+
end
|
180
|
+
rescue LoadError => e
|
181
|
+
Merb.logger.warn!("The #{template_engine_plugin} gem was not found. You may need to install it.")
|
182
|
+
raise e
|
186
183
|
end
|
187
184
|
|
188
185
|
# @param i<Fixnum> The caller number. Defaults to 1.
|
data/lib/merb-core/core_ext.rb
CHANGED
@@ -18,10 +18,10 @@ module Merb
|
|
18
18
|
filename, lineno, location = line.split(":")
|
19
19
|
if filename.index(Merb.framework_root)
|
20
20
|
type = "framework"
|
21
|
-
shortname = Pathname.new(filename).relative_path_from(Merb.framework_root)
|
21
|
+
shortname = Pathname.new(filename).relative_path_from(Pathname.new(Merb.framework_root))
|
22
22
|
elsif filename.index(Merb.root)
|
23
23
|
type = "app"
|
24
|
-
shortname = Pathname.new(filename).relative_path_from(Merb.root)
|
24
|
+
shortname = Pathname.new(filename).relative_path_from(Pathname.new(Merb.root))
|
25
25
|
elsif path = Gem.path.find {|p| filename.index(p)}
|
26
26
|
type = "gem"
|
27
27
|
shortname = Pathname.new(filename).relative_path_from(Pathname.new(path))
|
@@ -90,4 +90,4 @@ module Merb
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
93
|
-
end
|
93
|
+
end
|