aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-07-25 12:55:01 +0100
committerPratik Naik <pratiknaik@gmail.com>2009-07-25 12:55:01 +0100
commitc6b16fc2aada37aab1949cd9a1e46a2d9ccc8381 (patch)
treeea13a4e420a94ed7b552529ca9dc4b02680203d2 /actionpack/lib/action_view
parentf2d65a456fd93fd3a220f85c1001f0180bfdd6be (diff)
parent0c68d23f19010379a9320690ca17a26743c8f071 (diff)
downloadrails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.tar.gz
rails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.tar.bz2
rails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.zip
Merge commit 'mainstream/master'
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb13
-rw-r--r--actionpack/lib/action_view/context.rb44
-rw-r--r--actionpack/lib/action_view/helpers.rb5
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb (renamed from actionpack/lib/action_view/helpers/active_record_helper.rb)26
-rw-r--r--actionpack/lib/action_view/helpers/ajax_helper.rb68
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb38
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb35
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb3
-rw-r--r--actionpack/lib/action_view/render/partials.rb6
-rw-r--r--actionpack/lib/action_view/template/renderable.rb8
-rw-r--r--actionpack/lib/action_view/template/template.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb1
12 files changed, 213 insertions, 36 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 45184f58fb..9e696af83b 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -172,8 +172,6 @@ module ActionView #:nodoc:
attr_accessor :controller
attr_internal :captures
- attr_accessor :output_buffer
-
class << self
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
@@ -206,10 +204,7 @@ module ActionView #:nodoc:
delegate :find_by_parts, :to => :view_paths
- module CompiledTemplates #:nodoc:
- # holds compiled template code
- end
- include CompiledTemplates
+ include Context
def self.process_view_paths(value)
ActionView::PathSet.new(Array(value))
@@ -228,6 +223,12 @@ module ActionView #:nodoc:
end
end
+ def self.for_controller(controller)
+ new(controller.class.view_paths, {}, controller).tap do |view|
+ view.helpers.include(controller._helpers) if controller.respond_to?(:_helpers)
+ end
+ end
+
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
@formats = formats || [:html]
@assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb
new file mode 100644
index 0000000000..f212fe25eb
--- /dev/null
+++ b/actionpack/lib/action_view/context.rb
@@ -0,0 +1,44 @@
+module ActionView
+ module CompiledTemplates #:nodoc:
+ # holds compiled template code
+ end
+
+ # ActionView contexts are supplied to ActionController
+ # to render template. The default ActionView context
+ # is ActionView::Base.
+ #
+ # In order to work with ActionController, a Context
+ # must implement:
+ #
+ # Context.for_controller[controller] Create a new ActionView instance for a
+ # controller
+ # Context#_render_partial_from_controller[options]
+ # - responsible for setting options[:_template]
+ # - Returns String with the rendered partial
+ # options<Hash>:: see _render_partial in ActionView::Base
+ # Context#_render_template_from_controller[template, layout, options, partial]
+ # - Returns String with the rendered template
+ # template<ActionView::Template>:: The template to render
+ # layout<ActionView::Template>:: The layout to render around the template
+ # options<Hash>:: See _render_template_with_layout in ActionView::Base
+ # partial<Boolean>:: Whether or not the template to render is a partial
+ #
+ # An ActionView context can also mix in ActionView's
+ # helpers. In order to mix in helpers, a context must
+ # implement:
+ #
+ # Context#controller
+ # - Returns an instance of AbstractController
+ #
+ # In any case, a context must mix in ActionView::Context,
+ # which stores compiled template and provides the output
+ # buffer.
+ module Context
+ include CompiledTemplates
+ attr_accessor :output_buffer
+
+ def convert_to_model(object)
+ object.respond_to?(:to_model) ? object.to_model : object
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 97fa2d80e9..652561f7f8 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -1,6 +1,7 @@
module ActionView #:nodoc:
module Helpers #:nodoc:
- autoload :ActiveRecordHelper, 'action_view/helpers/active_record_helper'
+ autoload :ActiveModelHelper, 'action_view/helpers/active_model_helper'
+ autoload :AjaxHelper, 'action_view/helpers/ajax_helper'
autoload :AssetTagHelper, 'action_view/helpers/asset_tag_helper'
autoload :AtomFeedHelper, 'action_view/helpers/atom_feed_helper'
autoload :BenchmarkHelper, 'action_view/helpers/benchmark_helper'
@@ -31,7 +32,7 @@ module ActionView #:nodoc:
include SanitizeHelper::ClassMethods
end
- include ActiveRecordHelper
+ include ActiveModelHelper
include AssetTagHelper
include AtomFeedHelper
include BenchmarkHelper
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index 75cc651968..0f122d9232 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -15,7 +15,7 @@ module ActionView
# method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This
# is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form.
# In that case, it's better to use the +input+ method and the specialized +form+ methods in link:classes/ActionView/Helpers/FormHelper.html
- module ActiveRecordHelper
+ module ActiveModelHelper
# Returns a default input tag for the type of object returned by the method. For example, if <tt>@post</tt>
# has an attribute +title+ mapped to a +VARCHAR+ column that holds "Hello World":
#
@@ -77,6 +77,7 @@ module ActionView
# * <tt>:submit_value</tt> - The text of the submit button (default: "Create" if a new record, otherwise "Update").
def form(record_name, options = {})
record = instance_variable_get("@#{record_name}")
+ record = convert_to_model(record)
options = options.symbolize_keys
options[:action] ||= record.new_record? ? "create" : "update"
@@ -121,6 +122,8 @@ module ActionView
end
options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
+ object = convert_to_model(object)
+
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
(errors = obj.errors[method])
content_tag("div",
@@ -179,6 +182,8 @@ module ActionView
objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
end
+ objects.map! {|o| convert_to_model(o) }
+
count = objects.inject(0) {|sum, object| sum + object.errors.count }
unless count.zero?
html = {}
@@ -226,7 +231,14 @@ module ActionView
end
end
- class InstanceTag #:nodoc:
+ module ActiveRecordInstanceTag
+ def object
+ @active_model_object ||= begin
+ object = super
+ object.respond_to?(:to_model) ? object.to_model : object
+ end
+ end
+
def to_tag(options = {})
case column_type
when :string
@@ -248,11 +260,9 @@ module ActionView
end
%w(tag content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth|
- without = "#{meth}_without_error_wrapping"
- define_method "#{meth}_with_error_wrapping" do |*args|
- error_wrapping(send(without, *args))
+ define_method meth do |*|
+ error_wrapping(super)
end
- alias_method_chain meth, :error_wrapping
end
def error_wrapping(html_tag)
@@ -267,5 +277,9 @@ module ActionView
object.send(:column_for_attribute, @method_name).type
end
end
+
+ class InstanceTag
+ include ActiveRecordInstanceTag
+ end
end
end
diff --git a/actionpack/lib/action_view/helpers/ajax_helper.rb b/actionpack/lib/action_view/helpers/ajax_helper.rb
new file mode 100644
index 0000000000..9cc2acc239
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/ajax_helper.rb
@@ -0,0 +1,68 @@
+module ActionView
+ module Helpers
+ module AjaxHelper
+ include UrlHelper
+
+ def link_to_remote(name, url, options = {})
+ html = options.delete(:html) || {}
+
+ update = options.delete(:update)
+ if update.is_a?(Hash)
+ html["data-update-success"] = update[:success]
+ html["data-update-failure"] = update[:failure]
+ else
+ html["data-update-success"] = update
+ end
+
+ html["data-update-position"] = options.delete(:position)
+ html["data-method"] = options.delete(:method)
+ html["data-remote"] = "true"
+
+ html.merge!(options)
+
+ url = url_for(url) if url.is_a?(Hash)
+ link_to(name, url, html)
+ end
+
+ def button_to_remote(name, options = {}, html_options = {})
+ url = options.delete(:url)
+ url = url_for(url) if url.is_a?(Hash)
+
+ html_options.merge!(:type => "button", :value => name,
+ :"data-url" => url)
+
+ tag(:input, html_options)
+ end
+
+ module Rails2Compatibility
+ def set_callbacks(options, html)
+ [:complete, :failure, :success, :interactive, :loaded, :loading].each do |type|
+ html["data-#{type}-code"] = options.delete(type.to_sym)
+ end
+
+ options.each do |option, value|
+ if option.is_a?(Integer)
+ html["data-#{option}-code"] = options.delete(option)
+ end
+ end
+ end
+
+ def link_to_remote(name, url, options = nil)
+ if !options && url.is_a?(Hash) && url.key?(:url)
+ url, options = url.delete(:url), url
+ end
+
+ set_callbacks(options, options[:html] ||= {})
+
+ super
+ end
+
+ def button_to_remote(name, options = {}, html_options = {})
+ set_callbacks(options, html_options)
+ super
+ end
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 898da3c7e4..5025891d25 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -465,12 +465,27 @@ module ActionView
# video_path("hd") # => /videos/hd
# video_path("hd.avi") # => /videos/hd.avi
# video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
- # video_path("/trailers/hd.avi") # => /videos/hd.avi
+ # video_path("/trailers/hd.avi") # => /trailers/hd.avi
# video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi
def video_path(source)
compute_public_path(source, 'videos')
end
- alias_method :path_to_video, :video_path # aliased to avoid conflicts with an video_path named route
+ alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route
+
+ # Computes the path to an audio asset in the public audios directory.
+ # Full paths from the document root will be passed through.
+ # Used internally by +audio_tag+ to build the audio path.
+ #
+ # ==== Examples
+ # audio_path("horse") # => /audios/horse
+ # audio_path("horse.wav") # => /audios/horse.avi
+ # audio_path("sounds/horse.wav") # => /audios/sounds/horse.avi
+ # audio_path("/sounds/horse.wav") # => /sounds/horse.avi
+ # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav
+ def audio_path(source)
+ compute_public_path(source, 'audios')
+ end
+ alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
# Returns an html image tag for the +source+. The +source+ can be a full
# path or a file that exists in your public images directory.
@@ -545,7 +560,7 @@ module ActionView
# video_tag("trailer.ogg") # =>
# <video src="/videos/trailer.ogg" />
# video_tag("trailer.ogg", :controls => true, :autobuffer => true) # =>
- # <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" />
+ # <video autobuffer="true" controls="true" src="/videos/trailer.ogg" />
# video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # =>
# <video src="/videos/trailer.m4v" width="16" height="10" poster="/images/screenshot.png" />
# video_tag("/trailers/hd.avi", :size => "16x16") # =>
@@ -575,6 +590,23 @@ module ActionView
end
end
+ # Returns an html audio tag for the +source+.
+ # The +source+ can be full path or file that exists in
+ # your public audios directory.
+ #
+ # ==== Examples
+ # audio_tag("sound") # =>
+ # <audio src="/audios/sound" />
+ # audio_tag("sound.wav") # =>
+ # <audio src="/audios/sound.wav" />
+ # audio_tag("sound.wav", :autoplay => true, :controls => true) # =>
+ # <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" />
+ def audio_tag(source, options = {})
+ options.symbolize_keys!
+ options[:src] = path_to_audio(source)
+ tag("audio", options)
+ end
+
def self.cache_asset_timestamps
@@cache_asset_timestamps
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 6d6d623938..2d1d19d5f3 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -288,6 +288,8 @@ module ActionView
def apply_form_for_options!(object_or_array, options) #:nodoc:
object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array
+ object = convert_to_model(object)
+
html_options =
if object.respond_to?(:new_record?) && object.new_record?
{ :class => dom_class(object, :new), :id => dom_id(object), :method => :post }
@@ -488,7 +490,7 @@ module ActionView
object_name = ActionController::RecordIdentifier.singular_class_name(object)
end
- builder = options[:builder] || ActionView::Base.default_form_builder
+ builder = options[:builder] || ActionView.default_form_builder
yield builder.new(object_name, object, self, options, block)
end
@@ -626,8 +628,8 @@ module ActionView
# Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
# assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object.
- # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
- # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
+ # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
+ # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
# while the default +unchecked_value+ is set to 0 which is convenient for boolean values.
#
# ==== Gotcha
@@ -709,7 +711,8 @@ module ActionView
end
end
- class InstanceTag #:nodoc:
+ module InstanceTagMethods #:nodoc:
+ extend ActiveSupport::Concern
include Helpers::TagHelper, Helpers::FormTagHelper
attr_reader :method_name, :object_name
@@ -832,7 +835,7 @@ module ActionView
self.class.value_before_type_cast(object, @method_name)
end
- class << self
+ module ClassMethods
def value(object, method_name)
object.send method_name unless object.nil?
end
@@ -918,6 +921,10 @@ module ActionView
end
end
+ class InstanceTag
+ include InstanceTagMethods
+ end
+
class FormBuilder #:nodoc:
# The methods which wrap a form helper call.
class_inheritable_accessor :field_helpers
@@ -1022,7 +1029,7 @@ module ActionView
def fields_for_with_nested_attributes(association_name, args, block)
name = "#{object_name}[#{association_name}_attributes]"
association = @object.send(association_name)
- explicit_object = args.first if args.first.respond_to?(:new_record?)
+ explicit_object = args.first.to_model if args.first.respond_to?(:to_model)
if association.is_a?(Array)
children = explicit_object ? [explicit_object] : association
@@ -1054,9 +1061,21 @@ module ActionView
end
end
- class << Base
+ class << ActionView
attr_accessor :default_form_builder
end
- Base.default_form_builder = ::ActionView::Helpers::FormBuilder
+ self.default_form_builder = ::ActionView::Helpers::FormBuilder
+
+ # 2.3 compatibility
+ class << Base
+ def default_form_builder=(builder)
+ ActionView.default_form_builder = builder
+ end
+
+ def default_form_builder
+ ActionView.default_form_builder
+ end
+ end
+
end
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 9b6e9d201f..66d7592874 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -8,8 +8,7 @@ module ActionView
module TagHelper
include ERB::Util
- BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
- autoplay controls loop).to_set
+ BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym })
# Returns an empty HTML tag of type +name+ which by default is XHTML
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index a80ffe3c20..ccb14d513a 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -259,7 +259,7 @@ module ActionView
_set_locals(object, locals, template, options)
- self._partial = template
+ options[:_template] = template
_render_template(template, locals)
end
@@ -278,7 +278,7 @@ module ActionView
locals = (options[:locals] ||= {})
index, @_partial_path = 0, nil
collection.map do |object|
- template = passed_template || begin
+ options[:_template] = template = passed_template || begin
_partial_path =
ActionController::RecordIdentifier.partial_path(object, controller_path)
template = _pick_partial_template(_partial_path)
@@ -289,8 +289,6 @@ module ActionView
index += 1
- self._partial = template
-
_render_template(template, locals)
end.join(spacer)
end
diff --git a/actionpack/lib/action_view/template/renderable.rb b/actionpack/lib/action_view/template/renderable.rb
index 54857516ab..7687578165 100644
--- a/actionpack/lib/action_view/template/renderable.rb
+++ b/actionpack/lib/action_view/template/renderable.rb
@@ -12,9 +12,9 @@ module ActionView
end
def load!
- names = Base::CompiledTemplates.instance_methods.grep(/#{method_name_without_locals}/)
+ names = CompiledTemplates.instance_methods.grep(/#{method_name_without_locals}/)
names.each do |name|
- Base::CompiledTemplates.class_eval do
+ CompiledTemplates.class_eval do
remove_method(name)
end
end
@@ -56,7 +56,7 @@ module ActionView
def compile(local_assigns)
render_symbol = method_name(local_assigns)
- if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?
+ if !CompiledTemplates.method_defined?(render_symbol) || recompile?
compile!(render_symbol, local_assigns)
end
end
@@ -74,7 +74,7 @@ module ActionView
end_src
begin
- ActionView::Base::CompiledTemplates.module_eval(source, filename.to_s, 0)
+ ActionView::CompiledTemplates.module_eval(source, filename.to_s, 0)
rescue Exception => e # errors from template code
if logger = defined?(ActionController) && Base.logger
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb
index fac50cd692..4145045e2d 100644
--- a/actionpack/lib/action_view/template/template.rb
+++ b/actionpack/lib/action_view/template/template.rb
@@ -75,7 +75,7 @@ module ActionView
end
begin
- ActionView::Base::CompiledTemplates.module_eval(source, identifier, line)
+ ActionView::CompiledTemplates.module_eval(source, identifier, line)
method_name
rescue Exception => e # errors from template code
if logger = (view && view.logger)
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 7355af4192..3f3951509a 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -23,6 +23,7 @@ module ActionView
class TestCase < ActiveSupport::TestCase
include ActionDispatch::Assertions
include ActionController::TestProcess
+ include ActionView::Context
class_inheritable_accessor :helper_class
@@helper_class = nil