lib/action_view/base.rb in actionpack-3.0.0.beta vs lib/action_view/base.rb in actionpack-3.0.0.beta2

- old
+ new

@@ -1,31 +1,14 @@ require 'active_support/core_ext/module/attr_internal' require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/array/wrap' module ActionView #:nodoc: - class ActionViewError < StandardError #:nodoc: + class NonConcattingString < ActiveSupport::SafeBuffer end - class MissingTemplate < ActionViewError #:nodoc: - attr_reader :path - - def initialize(paths, path, details, partial) - @path = path - display_paths = paths.compact.join(":") - template_type = if partial - "partial" - elsif path =~ /layouts/i - 'layout' - else - 'template' - end - - super("Missing #{template_type} #{path} with #{details.inspect} in view path #{display_paths}") - end - end - # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used. # If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator. # # = ERb @@ -171,145 +154,74 @@ # See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details. class Base module Subclasses end - include Helpers, Rendering, Partials, ::ERB::Util + include Helpers, Rendering, Partials, Layouts, ::ERB::Util, Context + extend ActiveSupport::Memoizable - def config - self.config = DEFAULT_CONFIG unless @config - @config - end + # Specify whether RJS responses should be wrapped in a try/catch block + # that alert()s the caught exception (and then re-raises it). + cattr_accessor :debug_rjs + @@debug_rjs = false - def config=(config) - @config = ActiveSupport::OrderedOptions.new.merge(config) - end + class_attribute :helpers + remove_method :helpers + attr_reader :helpers - extend ActiveSupport::Memoizable - - attr_accessor :base_path, :assigns, :template_extension, :formats - attr_internal :captures - - def reset_formats(formats) - @formats = formats - - if defined?(AbstractController::HashKey) - # This is expensive, but we need to reset this when the format is updated, - # which currently only happens - Thread.current[:format_locale_key] = - AbstractController::HashKey.get(self.class, formats, I18n.locale) - end - end - class << self delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true end - @@debug_rjs = false - ## - # :singleton-method: - # Specify whether RJS responses should be wrapped in a try/catch block - # that alert()s the caught exception (and then re-raises it). - cattr_accessor :debug_rjs + ActiveSupport.run_load_hooks(:action_view, self) - # Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed. - # Automatically reloading templates are not thread safe and should only be used in development mode. - @@cache_template_loading = nil - cattr_accessor :cache_template_loading + attr_accessor :base_path, :assigns, :template_extension, :lookup_context + attr_internal :captures, :request, :controller, :template, :config - # :nodoc: - def self.xss_safe? - true - end + delegate :find_template, :template_exists?, :formats, :formats=, :locale, :locale=, + :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context - def self.cache_template_loading? - ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading) - end - - attr_internal :request, :layout - - def controller_path - @controller_path ||= controller && controller.controller_path - end - delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, :flash, :action_name, :controller_name, :to => :controller delegate :logger, :to => :controller, :allow_nil => true - delegate :find, :to => :view_paths + # TODO: HACK FOR RJS + def view_context + self + end - include Context + def self.xss_safe? #:nodoc: + true + end def self.process_view_paths(value) - ActionView::PathSet.new(Array(value)) + ActionView::PathSet.new(Array.wrap(value)) end - class_attribute :helpers - attr_reader :helpers - - def self.for_controller(controller) - @views ||= {} - - # TODO: Decouple this so helpers are a separate concern in AV just like - # they are in AC. - if controller.class.respond_to?(:_helper_serial) - klass = @views[controller.class._helper_serial] ||= Class.new(self) do - # Try to make stack traces clearer - class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def self.name - "ActionView for #{controller.class}" - end - - def inspect - "#<#{self.class.name}>" - end - ruby_eval - - if controller.respond_to?(:_helpers) - include controller._helpers - self.helpers = controller._helpers - end - end - else - klass = self - end - - klass.new(controller.class.view_paths, {}, controller) - end - - def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: + def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil - @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @helpers = self.class.helpers || Module.new @_controller = controller - @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } + @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller && controller.respond_to?(:config) + @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil - self.view_paths = view_paths + + @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ? + lookup_context : ActionView::LookupContext.new(lookup_context) + @lookup_context.formats = formats if formats end - attr_internal :controller, :template - attr_reader :view_paths - - def view_paths=(paths) - @view_paths = self.class.process_view_paths(paths) + def controller_path + @controller_path ||= controller && controller.controller_path end def punctuate_body!(part) flush_output_buffer response.body_parts << part nil - end - - # Evaluates the local assigns and controller ivars, pushes them to the view. - def _evaluate_assigns_and_ivars #:nodoc: - if controller - variables = controller.instance_variable_names - 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 end end end