aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb170
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb10
-rw-r--r--actionpack/lib/action_view/partials.rb2
-rw-r--r--actionpack/lib/action_view/renderable.rb8
-rw-r--r--actionpack/lib/action_view/template_handlers/builder.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb2
6 files changed, 110 insertions, 84 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index c65048bfa0..6c4da9067d 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -162,7 +162,6 @@ module ActionView #:nodoc:
attr_accessor :base_path, :assigns, :template_extension
attr_accessor :controller
- attr_accessor :_first_render, :_last_render
attr_writer :template_format
@@ -185,6 +184,17 @@ module ActionView #:nodoc:
"deprecated and has no effect. Please remove it from your config files.", caller)
end
+ # Templates that are exempt from layouts
+ @@exempt_from_layout = Set.new([/\.rjs$/])
+
+ # Don't render layouts for templates with the given extensions.
+ def self.exempt_from_layout(*extensions)
+ regexps = extensions.collect do |extension|
+ extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
+ end
+ @@exempt_from_layout.merge(regexps)
+ end
+
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
@@ -246,33 +256,20 @@ module ActionView #:nodoc:
update_page(&block)
elsif options.is_a?(Hash)
options = options.reverse_merge(:locals => {})
-
- if partial_layout = options.delete(:layout)
- if block_given?
- begin
- @_proc_for_layout = block
- concat(render(options.merge(:partial => partial_layout)))
- ensure
- @_proc_for_layout = nil
- end
- else
- begin
- original_content_for_layout, @content_for_layout = @content_for_layout, render(options)
- render(options.merge(:partial => partial_layout))
- ensure
- @content_for_layout = original_content_for_layout
- end
- end
+ if options[:layout]
+ _render_with_layout(options, local_assigns, &block)
elsif options[:file]
if options[:use_full_path]
ActiveSupport::Deprecation.warn("use_full_path option has been deprecated and has no affect.", caller)
end
- pick_template(options[:file]).render_template(self, options[:locals])
+ _pick_template(options[:file]).render_template(self, options[:locals])
elsif options[:partial]
render_partial(options)
elsif options[:inline]
InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
+ elsif options[:text]
+ options[:text]
end
end
end
@@ -290,74 +287,95 @@ module ActionView #:nodoc:
end
end
- def file_exists?(template_path)
- pick_template(template_path) ? true : false
- rescue MissingTemplate
- false
- end
+ private
+ attr_accessor :_first_render, :_last_render
- # Gets the extension for an existing template with the given template_path.
- # Returns the format with the extension if that template exists.
- #
- # pick_template('users/show')
- # # => 'users/show.html.erb'
- #
- # pick_template('users/legacy')
- # # => 'users/legacy.rhtml'
- #
- def pick_template(template_path)
- return template_path if template_path.respond_to?(:render)
-
- path = template_path.sub(/^\//, '')
- if m = path.match(/(.*)\.(\w+)$/)
- template_file_name, template_file_extension = m[1], m[2]
- else
- template_file_name = path
- end
+ # Evaluate the local assigns and pushes them to the view.
+ def _evaluate_assigns_and_ivars #:nodoc:
+ unless @assigns_added
+ @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
- # OPTIMIZE: Checks to lookup template in view path
- if template = self.view_paths["#{template_file_name}.#{template_format}"]
- template
- elsif template = self.view_paths[template_file_name]
- template
- elsif _first_render && template = self.view_paths["#{template_file_name}.#{_first_render.format_and_extension}"]
- template
- elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
- @template_format = :html
- template
- else
- template = Template.new(template_path, view_paths)
-
- if self.class.warn_cache_misses && logger
- logger.debug "[PERFORMANCE] Rendering a template that was " +
- "not found in view path. Templates outside the view path are " +
- "not cached and result in expensive disk operations. Move this " +
- "file into #{view_paths.join(':')} or add the folder to your " +
- "view path list"
+ if @controller
+ variables = @controller.instance_variables
+ variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
+ variables.each {|name| instance_variable_set(name, @controller.instance_variable_get(name)) }
+ end
+
+ @assigns_added = true
end
+ end
- template
+ def _set_controller_content_type(content_type) #:nodoc:
+ if controller.respond_to?(:response)
+ controller.response.content_type ||= content_type
+ end
end
- end
- memoize :pick_template
- private
- # Evaluate the local assigns and pushes them to the view.
- def evaluate_assigns
- unless @assigns_added
- assign_variables_from_controller
- @assigns_added = true
+ def _pick_template(template_path)
+ return template_path if template_path.respond_to?(:render)
+
+ path = template_path.sub(/^\//, '')
+ if m = path.match(/(.*)\.(\w+)$/)
+ template_file_name, template_file_extension = m[1], m[2]
+ else
+ template_file_name = path
+ end
+
+ # OPTIMIZE: Checks to lookup template in view path
+ if template = self.view_paths["#{template_file_name}.#{template_format}"]
+ template
+ elsif template = self.view_paths[template_file_name]
+ template
+ elsif _first_render && template = self.view_paths["#{template_file_name}.#{_first_render.format_and_extension}"]
+ template
+ elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
+ @template_format = :html
+ template
+ else
+ template = Template.new(template_path, view_paths)
+
+ if self.class.warn_cache_misses && logger
+ logger.debug "[PERFORMANCE] Rendering a template that was " +
+ "not found in view path. Templates outside the view path are " +
+ "not cached and result in expensive disk operations. Move this " +
+ "file into #{view_paths.join(':')} or add the folder to your " +
+ "view path list"
+ end
+
+ template
end
end
+ memoize :_pick_template
- # Assigns instance variables from the controller to the view.
- def assign_variables_from_controller
- @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
+ def _exempt_from_layout?(template_path) #:nodoc:
+ template = _pick_template(template_path).to_s
+ @@exempt_from_layout.any? { |ext| template =~ ext }
+ rescue ActionView::MissingTemplate
+ return false
end
- def set_controller_content_type(content_type)
- if controller.respond_to?(:response)
- controller.response.content_type ||= content_type
+ def _render_with_layout(options, local_assigns, &block) #:nodoc:
+ partial_layout = options.delete(:layout)
+
+ if block_given?
+ begin
+ @_proc_for_layout = block
+ concat(render(options.merge(:partial => partial_layout)))
+ ensure
+ @_proc_for_layout = nil
+ end
+ else
+ begin
+ original_content_for_layout, @content_for_layout = @content_for_layout, render(options)
+ if (options[:inline] || options[:file] || options[:text])
+ @cached_content_for_layout = @content_for_layout
+ render(:file => partial_layout, :locals => local_assigns)
+ else
+ render(options.merge(:partial => partial_layout))
+ end
+ ensure
+ @content_for_layout = original_content_for_layout
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index 2ce818cd71..2f08583b16 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -255,6 +255,14 @@ module ActionView
link_to_function(name, remote_function(options), html_options || options.delete(:html))
end
+ # Creates a button with an onclick event which calls a remote action
+ # via XMLHttpRequest
+ # The options for specifying the target with :url
+ # and defining callbacks is the same as link_to_remote.
+ def button_to_remote(name, options = {}, html_options = {})
+ button_to_function(name, remote_function(options), html_options)
+ end
+
# Periodically calls the specified url (<tt>options[:url]</tt>) every
# <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
# update a specified div (<tt>options[:update]</tt>) with the results
@@ -1052,7 +1060,7 @@ module ActionView
js_options['asynchronous'] = options[:type] != :synchronous
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
- js_options['insertion'] = options[:position].to_s.downcase if options[:position]
+ js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
js_options['evalScripts'] = options[:script].nil? || options[:script]
if options[:form]
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 443c49b870..373bb92dc4 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -196,7 +196,7 @@ module ActionView
path = "_#{partial_path}"
end
- pick_template(path)
+ _pick_template(path)
end
memoize :_pick_partial_template
end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index fa45edd436..d960335220 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -26,11 +26,11 @@ module ActionView
def render(view, local_assigns = {})
compile(local_assigns)
- view._first_render ||= self
- view._last_render = self
+ view.send(:_first_render=, self) unless view.send(:_first_render)
+ view.send(:_last_render=, self)
- view.send(:evaluate_assigns)
- view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type)
+ view.send(:_evaluate_assigns_and_ivars)
+ view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
view.send(method_name(local_assigns), local_assigns) do |*names|
if proc = view.instance_variable_get("@_proc_for_layout")
diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template_handlers/builder.rb
index 7d24a5c423..788dc93326 100644
--- a/actionpack/lib/action_view/template_handlers/builder.rb
+++ b/actionpack/lib/action_view/template_handlers/builder.rb
@@ -6,7 +6,7 @@ module ActionView
include Compilable
def compile(template)
- "set_controller_content_type(Mime::XML);" +
+ "_set_controller_content_type(Mime::XML);" +
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index adbb37fd09..c69f9455b2 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -54,7 +54,7 @@ module ActionView
private
def method_missing(selector, *args)
controller = TestController.new
- return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
+ return controller.__send__(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
super
end
end