merb-core 0.9.4 → 0.9.5
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/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
|