aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rwxr-xr-xactionpack/lib/action_controller/base.rb30
-rw-r--r--actionpack/lib/action_controller/layout.rb2
-rw-r--r--actionpack/lib/action_controller/mime_types.rb3
-rw-r--r--actionpack/lib/action_controller/rack_process.rb35
-rwxr-xr-xactionpack/lib/action_controller/request.rb13
-rw-r--r--actionpack/lib/action_controller/rescue.rb2
-rw-r--r--actionpack/lib/action_controller/routing/builder.rb3
-rw-r--r--actionpack/lib/action_controller/templates/rescues/diagnostics.erb4
-rw-r--r--actionpack/lib/action_controller/templates/rescues/template_error.erb4
-rw-r--r--actionpack/lib/action_view.rb2
-rw-r--r--actionpack/lib/action_view/base.rb105
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb10
-rw-r--r--actionpack/lib/action_view/helpers/cache_helper.rb2
-rwxr-xr-xactionpack/lib/action_view/helpers/date_helper.rb43
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb26
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb19
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb28
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb2
-rw-r--r--actionpack/lib/action_view/inline_template.rb11
-rw-r--r--actionpack/lib/action_view/partial_template.rb19
-rw-r--r--actionpack/lib/action_view/partials.rb14
-rw-r--r--actionpack/lib/action_view/renderer.rb29
-rw-r--r--actionpack/lib/action_view/template.rb77
-rw-r--r--actionpack/lib/action_view/template_file.rb10
-rw-r--r--actionpack/lib/action_view/template_handlers/compilable.rb8
-rw-r--r--actionpack/lib/action_view/view_load_paths.rb32
27 files changed, 290 insertions, 249 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 817b270feb..00d97793ee 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -702,6 +702,9 @@ module ActionController #:nodoc:
# # builds the complete response.
# render :partial => "person", :collection => @winners
#
+ # # Renders a collection of partials but with a custom local variable name
+ # render :partial => "admin_person", :collection => @winners, :as => :person
+ #
# # Renders the same collection of partials, but also renders the
# # person_divider partial between each person partial.
# render :partial => "person", :collection => @winners, :spacer_template => "person_divider"
@@ -733,6 +736,9 @@ module ActionController #:nodoc:
# # Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
# render :template => "weblog/show"
#
+ # # Renders the template with a local variable
+ # render :template => "weblog/show", :locals => {:customer => Customer.new}
+ #
# === Rendering a file
#
# File rendering works just like action rendering except that it takes a filesystem path. By default, the path
@@ -852,22 +858,21 @@ module ActionController #:nodoc:
else
if file = options[:file]
- render_for_file(file, options[:status], options[:use_full_path], options[:locals] || {})
+ render_for_file(file, options[:status], nil, options[:locals] || {})
elsif template = options[:template]
- render_for_file(template, options[:status], true)
+ render_for_file(template, options[:status], true, options[:locals] || {})
elsif inline = options[:inline]
add_variables_to_assigns
- tmpl = ActionView::InlineTemplate.new(@template, options[:inline], options[:locals], options[:type])
- render_for_text(@template.render_template(tmpl), options[:status])
+ render_for_text(@template.render(options), options[:status])
elsif action_name = options[:action]
template = default_template_name(action_name.to_s)
if options[:layout] && !template_exempt_from_layout?(template)
- render_with_a_layout(:file => template, :status => options[:status], :use_full_path => true, :layout => true)
+ render_with_a_layout(:file => template, :status => options[:status], :layout => true)
else
- render_with_no_layout(:file => template, :status => options[:status], :use_full_path => true)
+ render_with_no_layout(:file => template, :status => options[:status])
end
elsif xml = options[:xml]
@@ -887,12 +892,12 @@ module ActionController #:nodoc:
if collection = options[:collection]
render_for_text(
@template.send!(:render_partial_collection, partial, collection,
- options[:spacer_template], options[:locals]), options[:status]
+ options[:spacer_template], options[:locals], options[:as]), options[:status]
)
else
render_for_text(
@template.send!(:render_partial, partial,
- ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals]), options[:status]
+ options[:object], options[:locals]), options[:status]
)
end
@@ -1092,10 +1097,10 @@ module ActionController #:nodoc:
private
- def render_for_file(template_path, status = nil, use_full_path = false, locals = {}) #:nodoc:
+ def render_for_file(template_path, status = nil, use_full_path = nil, locals = {}) #:nodoc:
add_variables_to_assigns
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
- render_for_text(@template.render_file(template_path, use_full_path, locals), status)
+ render_for_text(@template.render(:file => template_path, :locals => locals), status)
end
def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
@@ -1230,8 +1235,9 @@ module ActionController #:nodoc:
end
def template_exempt_from_layout?(template_name = default_template_name)
- template_name = @template.send(:template_file_from_name, template_name) if @template
- @@exempt_from_layout.any? { |ext| template_name.to_s =~ ext }
+ extension = @template && @template.pick_template_extension(template_name)
+ name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name
+ @@exempt_from_layout.any? { |ext| name_with_extension =~ ext }
end
def default_template_name(action_name = self.action_name)
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb
index 0721f71498..d0c717ff67 100644
--- a/actionpack/lib/action_controller/layout.rb
+++ b/actionpack/lib/action_controller/layout.rb
@@ -254,7 +254,7 @@ module ActionController #:nodoc:
@template.instance_variable_set("@content_for_layout", content_for_layout)
response.layout = layout
status = template_with_options ? options[:status] : nil
- render_for_text(@template.render_file(layout, true), status)
+ render_for_text(@template.render(layout), status)
else
render_with_no_layout(options, extra_options, &block)
end
diff --git a/actionpack/lib/action_controller/mime_types.rb b/actionpack/lib/action_controller/mime_types.rb
index 01a266d3fe..2d7fba1173 100644
--- a/actionpack/lib/action_controller/mime_types.rb
+++ b/actionpack/lib/action_controller/mime_types.rb
@@ -17,4 +17,5 @@ Mime::Type.register "multipart/form-data", :multipart_form
Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form
# http://www.ietf.org/rfc/rfc4627.txt
-Mime::Type.register "application/json", :json, %w( text/x-json ) \ No newline at end of file
+# http://www.json.org/JSONRequest.html
+Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest ) \ No newline at end of file
diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb
index 58a0a9280d..3117fe2da5 100644
--- a/actionpack/lib/action_controller/rack_process.rb
+++ b/actionpack/lib/action_controller/rack_process.rb
@@ -24,6 +24,19 @@ module ActionController #:nodoc:
super()
end
+ %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO
+ PATH_TRANSLATED QUERY_STRING REMOTE_HOST
+ REMOTE_IDENT REMOTE_USER SCRIPT_NAME
+ SERVER_NAME SERVER_PROTOCOL
+
+ HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
+ HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST
+ HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|
+ define_method(env.sub(/^HTTP_/n, '').downcase) do
+ @env[env]
+ end
+ end
+
# The request body is an IO input stream. If the RAW_POST_DATA environment
# variable is already set, wrap it in a StringIO.
def body
@@ -35,7 +48,7 @@ module ActionController #:nodoc:
end
def key?(key)
- @env.key? key
+ @env.key?(key)
end
def query_parameters
@@ -85,6 +98,18 @@ module ActionController #:nodoc:
@env['REMOTE_ADDR']
end
+ def request_method
+ @env['REQUEST_METHOD'].downcase.to_sym
+ end
+
+ def server_port
+ @env['SERVER_PORT'].to_i
+ end
+
+ def server_software
+ @env['SERVER_SOFTWARE'].split("/").first
+ end
+
def session
unless defined?(@session)
if @session_options == false
@@ -178,9 +203,9 @@ end_msg
normalize_headers(@headers)
if [204, 304].include?(@status.to_i)
@headers.delete "Content-Type"
- [status.to_i, @headers.to_hash, []]
+ [status, @headers.to_hash, []]
else
- [status.to_i, @headers.to_hash, self]
+ [status, @headers.to_hash, self]
end
end
alias to_a out
@@ -225,8 +250,8 @@ end_msg
headers['Content-Language'] = options.delete('language') if options['language']
headers['Expires'] = options.delete('expires') if options['expires']
- @status = options.delete('Status') if options['Status']
- @status ||= 200
+ @status = options['Status'] || "200 OK"
+
# Convert 'cookie' header to 'Set-Cookie' headers.
# Because Set-Cookie header can appear more the once in the response body,
# we store it in a line break separated string that will be translated to
diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb
index 38f8e10fe7..2cd9672e1b 100755
--- a/actionpack/lib/action_controller/request.rb
+++ b/actionpack/lib/action_controller/request.rb
@@ -116,6 +116,19 @@ module ActionController
@format = Mime::Type.lookup_by_extension(parameters[:format])
end
+ def template_format
+ parameter_format = parameters[:format]
+
+ case
+ when parameter_format.blank? && !xhr?
+ :html
+ when parameter_format.blank? && xhr?
+ :js
+ else
+ parameter_format.to_sym
+ end
+ end
+
# Returns true if the request's "X-Requested-With" header contains
# "XMLHttpRequest". (The Prototype Javascript library sends this header with
# every Ajax request.)
diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb
index 40ef4ea044..163ed87fbb 100644
--- a/actionpack/lib/action_controller/rescue.rb
+++ b/actionpack/lib/action_controller/rescue.rb
@@ -178,7 +178,7 @@ module ActionController #:nodoc:
@template.instance_variable_set("@rescues_path", File.dirname(rescues_path("stub")))
@template.send!(:assign_variables_from_controller)
- @template.instance_variable_set("@contents", @template.render_file(template_path_for_local_rescue(exception), false))
+ @template.instance_variable_set("@contents", @template.render(:file => template_path_for_local_rescue(exception), :use_full_path => false))
response.content_type = Mime::HTML
render_for_file(rescues_path("layout"), response_code_for_rescue(exception))
diff --git a/actionpack/lib/action_controller/routing/builder.rb b/actionpack/lib/action_controller/routing/builder.rb
index 4740113ed0..b8323847fd 100644
--- a/actionpack/lib/action_controller/routing/builder.rb
+++ b/actionpack/lib/action_controller/routing/builder.rb
@@ -67,10 +67,9 @@ module ActionController
options = options.dup
if options[:namespace]
- options[:controller] = "#{options[:path_prefix]}/#{options[:controller]}"
+ options[:controller] = "#{options.delete(:namespace).sub(/\/$/, '')}/#{options[:controller]}"
options.delete(:path_prefix)
options.delete(:name_prefix)
- options.delete(:namespace)
end
requirements = (options.delete(:requirements) || {}).dup
diff --git a/actionpack/lib/action_controller/templates/rescues/diagnostics.erb b/actionpack/lib/action_controller/templates/rescues/diagnostics.erb
index 032f945ed2..385c6c1b09 100644
--- a/actionpack/lib/action_controller/templates/rescues/diagnostics.erb
+++ b/actionpack/lib/action_controller/templates/rescues/diagnostics.erb
@@ -6,6 +6,6 @@
</h1>
<pre><%=h @exception.clean_message %></pre>
-<%= render_file(@rescues_path + "/_trace.erb", false) %>
+<%= render(:file => @rescues_path + "/_trace.erb", :use_full_path => false) %>
-<%= render_file(@rescues_path + "/_request_and_response.erb", false) %>
+<%= render(:file => @rescues_path + "/_request_and_response.erb", :use_full_path => false) %>
diff --git a/actionpack/lib/action_controller/templates/rescues/template_error.erb b/actionpack/lib/action_controller/templates/rescues/template_error.erb
index eda64db3e9..4aecc68d18 100644
--- a/actionpack/lib/action_controller/templates/rescues/template_error.erb
+++ b/actionpack/lib/action_controller/templates/rescues/template_error.erb
@@ -15,7 +15,7 @@
<% @real_exception = @exception
@exception = @exception.original_exception || @exception %>
-<%= render_file(@rescues_path + "/_trace.erb", false) %>
+<%= render(:file => @rescues_path + "/_trace.erb", :use_full_path => false) %>
<% @exception = @real_exception %>
-<%= render_file(@rescues_path + "/_request_and_response.erb", false) %>
+<%= render(:file => @rescues_path + "/_request_and_response.erb", :use_full_path => false) %>
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 973020a768..49768fe264 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -24,6 +24,8 @@
require 'action_view/template_handlers'
require 'action_view/template_file'
require 'action_view/view_load_paths'
+
+require 'action_view/renderer'
require 'action_view/template'
require 'action_view/partial_template'
require 'action_view/inline_template'
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 91a86470d3..64e0ab575f 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -151,6 +151,7 @@ module ActionView #:nodoc:
#
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
class Base
+ extend TemplateHandlers
include ERB::Util
attr_accessor :base_path, :assigns, :template_extension, :first_render
@@ -199,9 +200,6 @@ module ActionView #:nodoc:
cattr_reader :computed_public_paths
@@computed_public_paths = {}
- class ObjectWrapper < Struct.new(:value) #:nodoc:
- end
-
def self.helper_modules #:nodoc:
helpers = []
Dir.entries(File.expand_path("#{File.dirname(__FILE__)}/helpers")).sort.each do |file|
@@ -228,36 +226,15 @@ module ActionView #:nodoc:
@view_paths = ViewLoadPaths.new(Array(paths))
end
- # Renders the template present at <tt>template_path</tt>. If <tt>use_full_path</tt> is set to true,
- # it's relative to the view_paths array, otherwise it's absolute. The hash in <tt>local_assigns</tt>
- # is made available as local variables.
- def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc:
- if defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) && !template_path.include?("/")
- raise ActionViewError, <<-END_ERROR
-Due to changes in ActionMailer, you need to provide the mailer_name along with the template name.
-
- render "user_mailer/signup"
- render :file => "user_mailer/signup"
-
-If you are rendering a subtemplate, you must now use controller-like partial syntax:
-
- render :partial => 'signup' # no mailer_name necessary
- END_ERROR
- end
-
- Template.new(self, template_path, use_full_path, local_assigns).render_template
- end
-
# Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
# The hash in <tt>local_assigns</tt> is made available as local variables.
def render(options = {}, local_assigns = {}, &block) #:nodoc:
if options.is_a?(String)
- render_file(options, true, local_assigns)
+ render_file(options, nil, local_assigns)
elsif options == :update
update_page(&block)
elsif options.is_a?(Hash)
- use_full_path = options[:use_full_path]
- options = options.reverse_merge(:locals => {}, :use_full_path => true)
+ options = options.reverse_merge(:locals => {})
if partial_layout = options.delete(:layout)
if block_given?
@@ -270,22 +247,17 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
end
end
elsif options[:file]
- render_file(options[:file], use_full_path || false, options[:locals])
+ render_file(options[:file], nil, options[:locals])
elsif options[:partial] && options[:collection]
- render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
+ render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as])
elsif options[:partial]
- render_partial(options[:partial], ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals])
+ render_partial(options[:partial], options[:object], options[:locals])
elsif options[:inline]
- template = InlineTemplate.new(self, options[:inline], options[:locals], options[:type])
- render_template(template)
+ render_inline(options[:inline], options[:locals], options[:type])
end
end
end
- def render_template(template) #:nodoc:
- template.render_template
- end
-
# Returns true is the file may be rendered implicitly.
def file_public?(template_path)#:nodoc:
template_path.split('/').last[0,1] != '_'
@@ -302,17 +274,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
return @template_format if @template_format
if controller && controller.respond_to?(:request)
- parameter_format = controller.request.parameters[:format]
- accept_format = controller.request.accepts.first
-
- case
- when parameter_format.blank? && accept_format != :js
- @template_format = :html
- when parameter_format.blank? && accept_format == :js
- @template_format = :js
- else
- @template_format = parameter_format.to_sym
- end
+ @template_format = controller.request.template_format
else
@template_format = :html
end
@@ -322,7 +284,45 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
view_paths.template_exists?(template_file_from_name(template_path))
end
+ # Gets the extension for an existing template with the given template_path.
+ # Returns the format with the extension if that template exists.
+ #
+ # pick_template_extension('users/show')
+ # # => 'html.erb'
+ #
+ # pick_template_extension('users/legacy')
+ # # => "rhtml"
+ #
+ def pick_template_extension(template_path)
+ if template = template_file_from_name(template_path)
+ template.extension
+ end
+ end
+
private
+ # Renders the template present at <tt>template_path</tt>. The hash in <tt>local_assigns</tt>
+ # is made available as local variables.
+ def render_file(template_path, use_full_path = nil, local_assigns = {}) #:nodoc:
+ if defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) && !template_path.include?("/")
+ raise ActionViewError, <<-END_ERROR
+ Due to changes in ActionMailer, you need to provide the mailer_name along with the template name.
+
+ render "user_mailer/signup"
+ render :file => "user_mailer/signup"
+
+ If you are rendering a subtemplate, you must now use controller-like partial syntax:
+
+ render :partial => 'signup' # no mailer_name necessary
+ END_ERROR
+ end
+
+ Template.new(self, template_path, use_full_path, local_assigns).render_template
+ end
+
+ def render_inline(text, local_assigns = {}, type = nil)
+ InlineTemplate.new(self, text, local_assigns, type).render
+ end
+
def wrap_content_for_layout(content)
original_content_for_layout, @content_for_layout = @content_for_layout, content
yield
@@ -351,19 +351,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
def template_file_from_name(template_name)
template_name = TemplateFile.from_path(template_name)
- pick_template_extension(template_name) unless template_name.extension
+ pick_template(template_name) unless template_name.extension
end
- # Gets the extension for an existing template with the given template_path.
- # Returns the format with the extension if that template exists.
- #
- # pick_template_extension('users/show')
- # # => 'html.erb'
- #
- # pick_template_extension('users/legacy')
- # # => "rhtml"
- #
- def pick_template_extension(file)
+ def pick_template(file)
if f = self.view_paths.find_template_file_for_path(file.dup_with_extension(template_format)) || file_from_first_render(file)
f
elsif template_format == :js && f = self.view_paths.find_template_file_for_path(file.dup_with_extension(:html))
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index e5a95a961c..0122de47af 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -243,7 +243,7 @@ module ActionView
joined_javascript_name = (cache == true ? "all" : cache) + ".js"
joined_javascript_path = File.join(JAVASCRIPTS_DIR, joined_javascript_name)
- write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources))
+ write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources)) unless File.exists?(joined_javascript_path)
javascript_src_tag(joined_javascript_name, options)
else
expand_javascript_sources(sources).collect { |source| javascript_src_tag(source, options) }.join("\n")
@@ -370,7 +370,7 @@ module ActionView
joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
joined_stylesheet_path = File.join(STYLESHEETS_DIR, joined_stylesheet_name)
- write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources))
+ write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources)) unless File.exists?(joined_stylesheet_path)
stylesheet_tag(joined_stylesheet_name, options)
else
expand_stylesheet_sources(sources).collect { |source| stylesheet_tag(source, options) }.join("\n")
@@ -601,10 +601,8 @@ module ActionView
end
def write_asset_file_contents(joined_asset_path, asset_paths)
- unless file_exist?(joined_asset_path)
- FileUtils.mkdir_p(File.dirname(joined_asset_path))
- File.open(joined_asset_path, "w+") { |cache| cache.write(join_asset_file_contents(asset_paths)) }
- end
+ FileUtils.mkdir_p(File.dirname(joined_asset_path))
+ File.open(joined_asset_path, "w+") { |cache| cache.write(join_asset_file_contents(asset_paths)) }
end
end
end
diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb
index 930c397785..c2aab5aa72 100644
--- a/actionpack/lib/action_view/helpers/cache_helper.rb
+++ b/actionpack/lib/action_view/helpers/cache_helper.rb
@@ -32,7 +32,7 @@ module ActionView
# <i>Topics listed alphabetically</i>
# <% end %>
def cache(name = {}, options = nil, &block)
- handler = Template.handler_class_for_extension(current_render_extension.to_sym)
+ handler = Base.handler_class_for_extension(current_render_extension.to_sym)
handler.new(@controller).cache_fragment(block, name, options)
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index b44e0f3bf5..17497481e6 100755
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -153,7 +153,7 @@ module ActionView
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month
# choices are valid.
def date_select(object_name, method, options = {}, html_options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_date_select_tag(options, html_options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_date_select_tag(options, html_options)
end
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a specified
@@ -188,7 +188,7 @@ module ActionView
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month
# choices are valid.
def time_select(object_name, method, options = {}, html_options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_time_select_tag(options, html_options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_time_select_tag(options, html_options)
end
# Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based
@@ -214,7 +214,7 @@ module ActionView
#
# The selects are prepared for multi-parameter assignment to an Active Record object.
def datetime_select(object_name, method, options = {}, html_options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_datetime_select_tag(options, html_options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options)
end
# Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the +datetime+.
@@ -547,23 +547,32 @@ module ActionView
# select_year(2006, :start_year => 2000, :end_year => 2010)
#
def select_year(date, options = {}, html_options = {})
- val = date ? (date.kind_of?(Fixnum) ? date : date.year) : ''
+ if !date || date == 0
+ value = ''
+ middle_year = Date.today.year
+ elsif date.kind_of?(Fixnum)
+ value = middle_year = date
+ else
+ value = middle_year = date.year
+ end
+
if options[:use_hidden]
- hidden_html(options[:field_name] || 'year', val, options)
+ hidden_html(options[:field_name] || 'year', value, options)
else
- year_options = []
- y = date ? (date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year) : Date.today.year
+ year_options = ''
+ start_year = options[:start_year] || middle_year - 5
+ end_year = options[:end_year] || middle_year + 5
+ step_val = start_year < end_year ? 1 : -1
- start_year, end_year = (options[:start_year] || y-5), (options[:end_year] || y+5)
- step_val = start_year < end_year ? 1 : -1
start_year.step(end_year, step_val) do |year|
- year_options << ((val == year) ?
- content_tag(:option, year, :value => year, :selected => "selected") :
- content_tag(:option, year, :value => year)
- )
+ if value == year
+ year_options << content_tag(:option, year, :value => year, :selected => "selected")
+ else
+ year_options << content_tag(:option, year, :value => year)
+ end
year_options << "\n"
end
- select_html(options[:field_name] || 'year', year_options.join, options, html_options)
+ select_html(options[:field_name] || 'year', year_options, options, html_options)
end
end
@@ -696,15 +705,15 @@ module ActionView
class FormBuilder
def date_select(method, options = {}, html_options = {})
- @template.date_select(@object_name, method, options.merge(:object => @object))
+ @template.date_select(@object_name, method, options.merge(:object => @object), html_options)
end
def time_select(method, options = {}, html_options = {})
- @template.time_select(@object_name, method, options.merge(:object => @object))
+ @template.time_select(@object_name, method, options.merge(:object => @object), html_options)
end
def datetime_select(method, options = {}, html_options = {})
- @template.datetime_select(@object_name, method, options.merge(:object => @object))
+ @template.datetime_select(@object_name, method, options.merge(:object => @object), html_options)
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index f952ada691..fa26aa4640 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -333,7 +333,7 @@ module ActionView
# # => <label for="post_title" class="title_label">A short title</label>
#
def label(object_name, method, text = nil, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_label_tag(text, options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options)
end
# Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object
@@ -355,7 +355,7 @@ module ActionView
# # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
#
def text_field(object_name, method, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("text", options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("text", options)
end
# Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object
@@ -377,7 +377,7 @@ module ActionView
# # => <input type="text" id="account_pin" name="account[pin]" size="20" value="#{@account.pin}" class="form_input" />
#
def password_field(object_name, method, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("password", options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", options)
end
# Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object
@@ -395,7 +395,7 @@ module ActionView
# hidden_field(:user, :token)
# # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
def hidden_field(object_name, method, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("hidden", options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("hidden", options)
end
# Returns an file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object
@@ -414,7 +414,7 @@ module ActionView
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
#
def file_field(object_name, method, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("file", options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options)
end
# Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+)
@@ -442,7 +442,7 @@ module ActionView
# # #{@entry.body}
# # </textarea>
def text_area(object_name, method, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_text_area_tag(options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_text_area_tag(options)
end
# Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
@@ -497,7 +497,7 @@ module ActionView
# # <input name="eula[accepted]" type="hidden" value="no" />
#
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value)
end
# Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
@@ -517,7 +517,7 @@ module ActionView
# # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
# # <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
def radio_button(object_name, method, tag_value, options = {})
- InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_radio_button_tag(tag_value, options)
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end
end
@@ -530,9 +530,9 @@ module ActionView
DEFAULT_RADIO_OPTIONS = { }.freeze unless const_defined?(:DEFAULT_RADIO_OPTIONS)
DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)
- def initialize(object_name, method_name, template_object, local_binding = nil, object = nil)
+ def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
- @template_object, @local_binding = template_object, local_binding
+ @template_object= template_object
@object = object
if @object_name.sub!(/\[\]$/,"")
if object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
@@ -630,7 +630,11 @@ module ActionView
end
def object
- @object || (@template_object.instance_variable_get("@#{@object_name}") rescue nil)
+ @object || @template_object.instance_variable_get("@#{@object_name}")
+ rescue NameError
+ # As @object_name may contain the nested syntax (item[subobject]) we
+ # need to fallback to nil.
+ nil
end
def value(object)
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index f22c12c9ad..0bd44c5aca 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -96,7 +96,7 @@ module ActionView
# By default, <tt>post.person_id</tt> is the selected option. Specify <tt>:selected => value</tt> to use a different selection
# or <tt>:selected => nil</tt> to leave all options unselected.
def select(object, method, choices, options = {}, html_options = {})
- InstanceTag.new(object, method, self, nil, options.delete(:object)).to_select_tag(choices, options, html_options)
+ InstanceTag.new(object, method, self, options.delete(:object)).to_select_tag(choices, options, html_options)
end
# Returns <tt><select></tt> and <tt><option></tt> tags for the collection of existing return values of
@@ -130,12 +130,12 @@ module ActionView
# <option value="3">M. Clark</option>
# </select>
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
- InstanceTag.new(object, method, self, nil, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options)
+ InstanceTag.new(object, method, self, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options)
end
# Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
def country_select(object, method, priority_countries = nil, options = {}, html_options = {})
- InstanceTag.new(object, method, self, nil, options.delete(:object)).to_country_select_tag(priority_countries, options, html_options)
+ InstanceTag.new(object, method, self, options.delete(:object)).to_country_select_tag(priority_countries, options, html_options)
end
# Return select and option tags for the given object and method, using
@@ -150,7 +150,8 @@ module ActionView
# You can also supply an array of TimeZone objects
# as +priority_zones+, so that they will be listed above the rest of the
# (long) list. (You can use TimeZone.us_zones as a convenience for
- # obtaining a list of the US time zones.)
+ # obtaining a list of the US time zones, or a Regexp to select the zones
+ # of your choice)
#
# Finally, this method supports a <tt>:default</tt> option, which selects
# a default TimeZone if the object's time zone is +nil+.
@@ -164,9 +165,11 @@ module ActionView
#
# time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ])
#
+ # time_zone_select( "user", 'time_zone', /Australia/)
+ #
# time_zone_select( "user", "time_zone", TZInfo::Timezone.all.sort, :model => TZInfo::Timezone)
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
- InstanceTag.new(object, method, self, nil, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
+ InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
end
# Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
@@ -294,7 +297,8 @@ module ActionView
# selected option tag. You can also supply an array of TimeZone objects
# as +priority_zones+, so that they will be listed above the rest of the
# (long) list. (You can use TimeZone.us_zones as a convenience for
- # obtaining a list of the US time zones.)
+ # obtaining a list of the US time zones, or a Regexp to select the zones
+ # of your choice)
#
# The +selected+ parameter must be either +nil+, or a string that names
# a TimeZone.
@@ -313,6 +317,9 @@ module ActionView
convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }
if priority_zones
+ if priority_zones.is_a?(Regexp)
+ priority_zones = model.all.find_all {|z| z =~ priority_zones}
+ end
zone_options += options_for_select(convert_zones[priority_zones], selected)
zone_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index ccebec3692..bdfb2eebd7 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -348,11 +348,13 @@ module ActionView
options.stringify_keys!
if disable_with = options.delete("disable_with")
+ disable_with = "this.value='#{disable_with}'"
+ disable_with << ";#{options.delete('onclick')}" if options['onclick']
+
options["onclick"] = [
"this.setAttribute('originalValue', this.value)",
"this.disabled=true",
- "this.value='#{disable_with}'",
- "#{options["onclick"]}",
+ disable_with,
"result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
"if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
"return result;",
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 00092adc87..6c2d76c85f 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -131,32 +131,6 @@ module ActionView
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
end
- # Includes the Action Pack JavaScript libraries inside a single <script>
- # tag. The function first includes prototype.js and then its core extensions,
- # (determined by filenames starting with "prototype").
- # Afterwards, any additional scripts will be included in undefined order.
- #
- # Note: The recommended approach is to copy the contents of
- # lib/action_view/helpers/javascripts/ into your application's
- # public/javascripts/ directory, and use +javascript_include_tag+ to
- # create remote <script> links.
- def define_javascript_functions
- javascript = "<script type=\"#{Mime::JS}\">"
-
- # load prototype.js and its extensions first
- prototype_libs = Dir.glob(File.join(JAVASCRIPT_PATH, 'prototype*')).sort.reverse
- prototype_libs.each do |filename|
- javascript << "\n" << IO.read(filename)
- end
-
- # load other libraries
- (Dir.glob(File.join(JAVASCRIPT_PATH, '*')) - prototype_libs).each do |filename|
- javascript << "\n" << IO.read(filename)
- end
- javascript << '</script>'
- end
-
-
JS_ESCAPE_MAP = {
'\\' => '\\\\',
'</' => '<\/',
@@ -233,7 +207,5 @@ module ActionView
end
end
end
-
- JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper
end
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index d98c5bd0d5..a6c48737e9 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -468,7 +468,7 @@ module ActionView
[-\w]+ # subdomain or domain
(?:\.[-\w]+)* # remaining subdomains or domain
(?::\d+)? # port
- (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:][^\s$]))+)?)* # path
+ (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))+)?)* # path
(?:\?[\w\+@%&=.;-]+)? # query string
(?:\#[\w\-]*)? # trailing anchor
)
diff --git a/actionpack/lib/action_view/inline_template.rb b/actionpack/lib/action_view/inline_template.rb
index fd0ad48302..19ab92ce1a 100644
--- a/actionpack/lib/action_view/inline_template.rb
+++ b/actionpack/lib/action_view/inline_template.rb
@@ -1,5 +1,7 @@
module ActionView #:nodoc:
- class InlineTemplate < Template #:nodoc:
+ class InlineTemplate #:nodoc:
+ include Renderer
+
def initialize(view, source, locals = {}, type = nil)
@view = view
@@ -7,11 +9,8 @@ module ActionView #:nodoc:
@extension = type
@locals = locals || {}
- @handler = self.class.handler_class_for_extension(@extension).new(@view)
- end
-
- def method_key
- @source
+ @method_key = @source
+ @handler = Base.handler_class_for_extension(@extension).new(@view)
end
end
end
diff --git a/actionpack/lib/action_view/partial_template.rb b/actionpack/lib/action_view/partial_template.rb
index 0cf996ca04..72f831e937 100644
--- a/actionpack/lib/action_view/partial_template.rb
+++ b/actionpack/lib/action_view/partial_template.rb
@@ -1,11 +1,12 @@
module ActionView #:nodoc:
class PartialTemplate < Template #:nodoc:
- attr_reader :variable_name, :object
+ attr_reader :variable_name, :object, :as
- def initialize(view, partial_path, object = nil, locals = {})
+ def initialize(view, partial_path, object = nil, locals = {}, as = nil)
@view_controller = view.controller if view.respond_to?(:controller)
+ @as = as
set_path_and_variable_name!(partial_path)
- super(view, @path, true, locals)
+ super(view, @path, nil, locals)
add_object_to_local_assigns!(object)
# This is needed here in order to compile template with knowledge of 'counter'
@@ -17,15 +18,17 @@ module ActionView #:nodoc:
def render
ActionController::Base.benchmark("Rendered #{@path.path_without_format_and_extension}", Logger::DEBUG, false) do
- @handler.render(self)
+ super
end
end
def render_member(object)
@locals[:object] = @locals[@variable_name] = object
+ @locals[as] = object if as
template = render_template
@locals[@counter_name] += 1
+ @locals.delete(as)
@locals.delete(@variable_name)
@locals.delete(:object)
@@ -39,12 +42,8 @@ module ActionView #:nodoc:
private
def add_object_to_local_assigns!(object)
@locals[:object] ||=
- @locals[@variable_name] ||=
- if object.is_a?(ActionView::Base::ObjectWrapper)
- object.value
- else
- object
- end || @view_controller.instance_variable_get("@#{variable_name}")
+ @locals[@variable_name] ||= object || @view_controller.instance_variable_get("@#{variable_name}")
+ @locals[as] ||= @locals[:object] if as
end
def set_path_and_variable_name!(partial_path)
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 6b294be6bd..7c6c98d611 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -123,32 +123,32 @@ module ActionView
end
end
- def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
+ def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc:
return " " if collection.empty?
local_assigns = local_assigns ? local_assigns.clone : {}
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
if partial_path.nil?
- render_partial_collection_with_unknown_partial_path(collection, local_assigns)
+ render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
else
- render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
+ render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
end.join(spacer)
end
- def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
- template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
+ def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
+ template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
collection.map do |element|
template.render_member(element)
end
end
- def render_partial_collection_with_unknown_partial_path(collection, local_assigns)
+ def render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
templates = Hash.new
i = 0
collection.map do |element|
partial_path = ActionController::RecordIdentifier.partial_path(element, controller.class.controller_path)
- template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
+ template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
template.counter = i
i += 1
template.render_member(element)
diff --git a/actionpack/lib/action_view/renderer.rb b/actionpack/lib/action_view/renderer.rb
new file mode 100644
index 0000000000..e6c64d2749
--- /dev/null
+++ b/actionpack/lib/action_view/renderer.rb
@@ -0,0 +1,29 @@
+module ActionView
+ module Renderer
+ # TODO: Local assigns should not be tied to template instance
+ attr_accessor :locals
+
+ # TODO: These readers should be private
+ attr_reader :filename, :source, :handler, :method_key, :method
+
+ def render
+ prepare!
+ @handler.render(self)
+ end
+
+ private
+ def prepare!
+ unless @prepared
+ @view.send(:evaluate_assigns)
+ @view.current_render_extension = @extension
+
+ if @handler.compilable?
+ @handler.compile_template(self) # compile the given template, if necessary
+ @method = @view.method_names[method_key] # Set the method name for this template and run it
+ end
+
+ @prepared = true
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index 4c3f252c10..8142232c8f 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -1,22 +1,31 @@
module ActionView #:nodoc:
class Template #:nodoc:
- extend TemplateHandlers
+ include Renderer
- attr_accessor :locals
- attr_reader :handler, :path, :extension, :filename, :method
+ class << self
+ # TODO: Deprecate
+ delegate :register_template_handler, :to => 'ActionView::Base'
+ end
+
+ attr_reader :path, :extension
+
+ def initialize(view, path, use_full_path = nil, locals = {})
+ unless use_full_path == nil
+ ActiveSupport::Deprecation.warn("use_full_path option has been deprecated and has no affect.", caller)
+ end
- def initialize(view, path, use_full_path, locals = {})
@view = view
@paths = view.view_paths
@original_path = path
- @path = TemplateFile.from_path(path, !use_full_path)
+ @path = TemplateFile.from_path(path)
@view.first_render ||= @path.to_s
- @source = nil # Don't read the source until we know that it is required
- set_extension_and_file_name(use_full_path)
+ set_extension_and_file_name
+
+ @method_key = @filename
@locals = locals || {}
- @handler = self.class.handler_class_for_extension(@extension).new(@view)
+ @handler = Base.handler_class_for_extension(@extension).new(@view)
end
def render_template
@@ -31,64 +40,40 @@ module ActionView #:nodoc:
end
end
- def render
- prepare!
- @handler.render(self)
- end
-
- def path_without_extension
- @path.path_without_extension
- end
-
def source
@source ||= File.read(self.filename)
end
- def method_key
- @filename
- end
-
def base_path_for_exception
(@paths.find_load_path_for_path(@path) || @paths.first).to_s
end
- def prepare!
- @view.send :evaluate_assigns
- @view.current_render_extension = @extension
-
- if @handler.compilable?
- @handler.compile_template(self) # compile the given template, if necessary
- @method = @view.method_names[method_key] # Set the method name for this template and run it
- end
- end
-
private
- def set_extension_and_file_name(use_full_path)
+ def set_extension_and_file_name
@extension = @path.extension
- if use_full_path
- unless @extension
- @path = @view.send(:template_file_from_name, @path)
- raise_missing_template_exception unless @path
- @extension = @path.extension
- end
+ unless @extension
+ @path = @view.send(:template_file_from_name, @path)
+ raise_missing_template_exception unless @path
+ @extension = @path.extension
+ end
- if @path = @paths.find_template_file_for_path(path)
- @filename = @path.full_path
- @extension = @path.extension
- end
- else
+ if p = @paths.find_template_file_for_path(path)
+ @path = p
@filename = @path.full_path
+ @extension = @path.extension
+ raise_missing_template_exception if @filename.blank?
+ else
+ @filename = @original_path
+ raise_missing_template_exception unless File.exist?(@filename)
end
-
- raise_missing_template_exception if @filename.blank?
end
def raise_missing_template_exception
full_template_path = @original_path.include?('.') ? @original_path : "#{@original_path}.#{@view.template_format}.erb"
display_paths = @paths.join(':')
template_type = (@original_path =~ /layouts/i) ? 'layout' : 'template'
- raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
+ raise MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}"
end
end
end
diff --git a/actionpack/lib/action_view/template_file.rb b/actionpack/lib/action_view/template_file.rb
index dd66482b3c..c38e8ed122 100644
--- a/actionpack/lib/action_view/template_file.rb
+++ b/actionpack/lib/action_view/template_file.rb
@@ -4,8 +4,8 @@ module ActionView #:nodoc:
# from the load path root e.g. "hello/index.html.erb" not
# "app/views/hello/index.html.erb"
class TemplateFile
- def self.from_path(path, use_full_path = false)
- path.is_a?(self) ? path : new(path, use_full_path)
+ def self.from_path(path)
+ path.is_a?(self) ? path : new(path)
end
def self.from_full_path(load_path, full_path)
@@ -17,11 +17,11 @@ module ActionView #:nodoc:
attr_accessor :load_path, :base_path, :name, :format, :extension
delegate :to_s, :inspect, :to => :path
- def initialize(path, use_full_path = false)
+ def initialize(path)
path = path.dup
- # Clear the forward slash in the beginning unless using full path
- trim_forward_slash!(path) unless use_full_path
+ # Clear the forward slash in the beginning
+ trim_forward_slash!(path)
@base_path, @name, @format, @extension = split(path)
end
diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb
index 783456ab53..f436ebbe45 100644
--- a/actionpack/lib/action_view/template_handlers/compilable.rb
+++ b/actionpack/lib/action_view/template_handlers/compilable.rb
@@ -41,10 +41,10 @@ module ActionView
file_name = template.filename || 'compiled-template'
ActionView::Base::CompiledTemplates.module_eval(render_source, file_name, -line_offset)
rescue Exception => e # errors from template code
- if @view.logger
- @view.logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
- @view.logger.debug "Function body: #{render_source}"
- @view.logger.debug "Backtrace: #{e.backtrace.join("\n")}"
+ if Base.logger
+ Base.logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
+ Base.logger.debug "Function body: #{render_source}"
+ Base.logger.debug "Backtrace: #{e.backtrace.join("\n")}"
end
raise ActionView::TemplateError.new(template, @view.assigns, e)
diff --git a/actionpack/lib/action_view/view_load_paths.rb b/actionpack/lib/action_view/view_load_paths.rb
index e873d96aa0..6e439a009c 100644
--- a/actionpack/lib/action_view/view_load_paths.rb
+++ b/actionpack/lib/action_view/view_load_paths.rb
@@ -6,19 +6,15 @@ module ActionView #:nodoc:
class LoadPath #:nodoc:
attr_reader :path, :paths
- delegate :to_s, :inspect, :to => :path
+ delegate :to_s, :to_str, :inspect, :to => :path
def initialize(path)
@path = path.freeze
reload!
end
- def eql?(view_path)
- view_path.is_a?(ViewPath) && @path == view_path.path
- end
-
- def hash
- @path.hash
+ def ==(path)
+ to_str == path.to_str
end
# Rebuild load path directory cache
@@ -33,12 +29,10 @@ module ActionView #:nodoc:
@paths.freeze
end
- # Tries to find the extension for the template name.
- # If it does not it exist, tries again without the format extension
- # find_template_file_for_partial_path('users/show') => 'html.erb'
- # find_template_file_for_partial_path('users/legacy') => 'rhtml'
- def find_template_file_for_partial_path(file)
- @paths[file.path] || @paths[file.path_without_extension] || @paths[file.path_without_format_and_extension]
+ def find_template_file_for_partial_path(template_path, template_format)
+ @paths["#{template_path}.#{template_format}"] ||
+ @paths[template_path] ||
+ @paths[template_path.gsub(/\..*$/, '')]
end
private
@@ -85,10 +79,10 @@ module ActionView #:nodoc:
find { |path| path.paths[file.to_s] }
end
- def find_template_file_for_path(file)
- file = TemplateFile.from_path(file)
+ def find_template_file_for_path(template_path)
+ template_path_without_extension, template_extension = path_and_extension(template_path.to_s)
each do |path|
- if f = path.find_template_file_for_partial_path(file)
+ if f = path.find_template_file_for_partial_path(template_path_without_extension, template_extension)
return f
end
end
@@ -99,5 +93,11 @@ module ActionView #:nodoc:
def delete_paths!(paths)
paths.each { |p1| delete_if { |p2| p1.to_s == p2.to_s } }
end
+
+ # Splits the path and extension from the given template_path and returns as an array.
+ def path_and_extension(template_path)
+ template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
+ [template_path_without_extension, $1]
+ end
end
end