From 4fad953f90f82e860a69d67745887b40d5b15475 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 12:00:23 -0700 Subject: Fixing pending tests and fixed some formats / partial rendering semantics --- actionpack/lib/action_view/base.rb | 2 ++ actionpack/lib/action_view/template/handlers/rjs.rb | 1 - actionpack/lib/action_view/template/path.rb | 3 +-- actionpack/lib/action_view/template/template.rb | 2 +- actionpack/lib/action_view/template/text.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 4ab568b44c..2d8f51300a 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -258,9 +258,11 @@ module ActionView #:nodoc: def with_template(current_template) last_template, self.template = template, current_template + old_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols yield ensure self.template = last_template + self.formats = old_formats end def punctuate_body!(part) diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb index a36744c2b7..b1d15dc209 100644 --- a/actionpack/lib/action_view/template/handlers/rjs.rb +++ b/actionpack/lib/action_view/template/handlers/rjs.rb @@ -6,7 +6,6 @@ module ActionView self.default_format = Mime::JS def compile(template) - "@formats = [:html];" + "controller.response.content_type ||= Mime::JS;" + "update_page do |page|;#{template.source}\nend" end diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb index 478bf96c9a..c3837a9f07 100644 --- a/actionpack/lib/action_view/template/path.rb +++ b/actionpack/lib/action_view/template/path.rb @@ -47,8 +47,7 @@ module ActionView def formats_glob @formats_glob ||= begin - formats = Mime::SET.map { |m| m.symbol } - '{' + formats.map { |l| ".#{l}," }.join + '}' + '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' end end diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index e7ea42c2eb..53aaa3dded 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -20,7 +20,7 @@ module ActionView handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html" end @mime_type = Mime::Type.lookup_by_extension(format.to_s) - @details[:formats] = Array.wrap(format && format.to_sym) + @details[:formats] = Array.wrap(format.to_sym) end def render(view, locals, &blk) diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index fd57b1677e..81944ff546 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -3,7 +3,7 @@ module ActionView #:nodoc: def initialize(string, content_type = Mime[:html]) super(string.to_s) - @content_type = Mime[content_type] + @content_type = Mime[content_type] || content_type end def details -- cgit v1.2.3 From d8f352e970ec86e8b791f9994465a3678a44281f Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 15:32:55 -0700 Subject: Rename ActionView::Template::Path ActionView::Resolver --- actionpack/lib/action_view/paths.rb | 2 +- actionpack/lib/action_view/template/path.rb | 249 ++++++++++++++-------------- 2 files changed, 125 insertions(+), 126 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 95c56faf9c..074b475819 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -3,7 +3,7 @@ module ActionView #:nodoc: def self.type_cast(obj) if obj.is_a?(String) cache = !defined?(Rails) || !Rails.respond_to?(:configuration) || Rails.configuration.cache_classes - Template::FileSystemPathWithFallback.new(obj, :cache => cache) + FileSystemResolverWithFallback.new(obj, :cache => cache) else obj end diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb index c3837a9f07..d15f53a11b 100644 --- a/actionpack/lib/action_view/template/path.rb +++ b/actionpack/lib/action_view/template/path.rb @@ -1,151 +1,150 @@ require "pathname" +require "action_view/template/template" module ActionView - class Template - # Abstract super class - class Path - def initialize(options) - @cache = options[:cache] - @cached = {} - end - - # Normalizes the arguments and passes it on to find_template - def find_by_parts(*args) - find_all_by_parts(*args).first - end - - def find_all_by_parts(name, details = {}, prefix = nil, partial = nil) - details[:locales] = [I18n.locale] - name = name.to_s.gsub(handler_matcher, '').split("/") - find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial) - end + # Abstract superclass + class Resolver + def initialize(options) + @cache = options[:cache] + @cached = {} + end + + # Normalizes the arguments and passes it on to find_template + def find_by_parts(*args) + find_all_by_parts(*args).first + end - private - - # This is what child classes implement. No defaults are needed - # because Path guarentees that the arguments are present and - # normalized. - def find_templates(name, details, prefix, partial) - raise NotImplementedError - end - - def valid_handlers - @valid_handlers ||= TemplateHandlers.extensions - end - - def handler_matcher - @handler_matcher ||= begin - e = valid_handlers.join('|') - /\.(?:#{e})$/ - end - end - - def handler_glob - e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join - "{#{e}}" - end - - def formats_glob - @formats_glob ||= begin - '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' - end - end - - def cached(key) - return yield unless @cache - return @cached[key] if @cached.key?(key) - @cached[key] = yield - end + def find_all_by_parts(name, details = {}, prefix = nil, partial = nil) + details[:locales] = [I18n.locale] + name = name.to_s.gsub(handler_matcher, '').split("/") + find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial) end - class FileSystemPath < Path + private + + # This is what child classes implement. No defaults are needed + # because Resolver guarantees that the arguments are present and + # normalized. + def find_templates(name, details, prefix, partial) + raise NotImplementedError + end - def initialize(path, options = {}) - raise ArgumentError, "path already is a Path class" if path.is_a?(Path) - super(options) - @path = Pathname.new(path).expand_path + def valid_handlers + @valid_handlers ||= TemplateHandlers.extensions + end + + def handler_matcher + @handler_matcher ||= begin + e = valid_handlers.join('|') + /\.(?:#{e})$/ end + end - # TODO: This is the currently needed API. Make this suck less - # ==== - attr_reader :path + def handler_glob + e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join + "{#{e}}" + end - def to_s - path.to_s + def formats_glob + @formats_glob ||= begin + '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' end + end - def to_str - path.to_s - end + def cached(key) + return yield unless @cache + return @cached[key] if @cached.key?(key) + @cached[key] = yield + end + end - def ==(path) - to_str == path.to_str - end + class FileSystemResolver < Resolver - def eql?(path) - to_str == path.to_str - end - # ==== - - def find_templates(name, details, prefix, partial, root = "#{@path}/") - if glob = details_to_glob(name, details, prefix, partial, root) - cached(glob) do - Dir[glob].map do |path| - next if File.directory?(path) - source = File.read(path) - identifier = Pathname.new(path).expand_path.to_s - - Template.new(source, identifier, *path_to_details(path)) - end.compact - end + def initialize(path, options = {}) + raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) + super(options) + @path = Pathname.new(path).expand_path + end + + # TODO: This is the currently needed API. Make this suck less + # ==== + attr_reader :path + + def to_s + path.to_s + end + + def to_str + path.to_s + end + + def ==(path) + to_str == path.to_str + end + + def eql?(path) + to_str == path.to_str + end + # ==== + + def find_templates(name, details, prefix, partial, root = "#{@path}/") + if glob = details_to_glob(name, details, prefix, partial, root) + cached(glob) do + Dir[glob].map do |path| + next if File.directory?(path) + source = File.read(path) + identifier = Pathname.new(path).expand_path.to_s + + Template.new(source, identifier, *path_to_details(path)) + end.compact end end - - private + end - # :api: plugin - def details_to_glob(name, details, prefix, partial, root) - path = "" - path << "#{prefix}/" unless prefix.empty? - path << (partial ? "_#{name}" : name) - - extensions = "" - [:locales, :formats].each do |k| - extensions << if exts = details[k] - '{' + exts.map {|e| ".#{e},"}.join + '}' - else - k == :formats ? formats_glob : '' - end + private + + # :api: plugin + def details_to_glob(name, details, prefix, partial, root) + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '{' + exts.map {|e| ".#{e},"}.join + '}' + else + k == :formats ? formats_glob : '' end - - "#{root}#{path}#{extensions}#{handler_glob}" end - # TODO: fix me - # :api: plugin - def path_to_details(path) - # [:erb, :format => :html, :locale => :en, :partial => true/false] - if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') - partial = m[1] == '_' - details = (m[2]||"").split('.').reject { |e| e.empty? } - handler = Template.handler_class_for_extension(m[3]) - - format = Mime[details.last] && details.pop.to_sym - locale = details.last && details.pop.to_sym - - return handler, :format => format, :locale => locale, :partial => partial - end - end + "#{root}#{path}#{extensions}#{handler_glob}" end - class FileSystemPathWithFallback < FileSystemPath - - def find_templates(name, details, prefix, partial) - templates = super - return super(name, details, prefix, partial, '') if templates.empty? - templates + # TODO: fix me + # :api: plugin + def path_to_details(path) + # [:erb, :format => :html, :locale => :en, :partial => true/false] + if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') + partial = m[1] == '_' + details = (m[2]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[3]) + + format = Mime[details.last] && details.pop.to_sym + locale = details.last && details.pop.to_sym + + return handler, :format => format, :locale => locale, :partial => partial end - end end + + class FileSystemResolverWithFallback < FileSystemResolver + + def find_templates(name, details, prefix, partial) + templates = super + return super(name, details, prefix, partial, '') if templates.empty? + templates + end + + end end \ No newline at end of file -- cgit v1.2.3 From 251a6e492c72d8aea713b7dabd245d68301e455d Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 15:39:41 -0700 Subject: Rename path.rb to resolver.rb --- actionpack/lib/action_view/template/path.rb | 150 ------------------------ actionpack/lib/action_view/template/resolver.rb | 150 ++++++++++++++++++++++++ actionpack/lib/action_view/template/template.rb | 2 +- 3 files changed, 151 insertions(+), 151 deletions(-) delete mode 100644 actionpack/lib/action_view/template/path.rb create mode 100644 actionpack/lib/action_view/template/resolver.rb (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb deleted file mode 100644 index d15f53a11b..0000000000 --- a/actionpack/lib/action_view/template/path.rb +++ /dev/null @@ -1,150 +0,0 @@ -require "pathname" -require "action_view/template/template" - -module ActionView - # Abstract superclass - class Resolver - def initialize(options) - @cache = options[:cache] - @cached = {} - end - - # Normalizes the arguments and passes it on to find_template - def find_by_parts(*args) - find_all_by_parts(*args).first - end - - def find_all_by_parts(name, details = {}, prefix = nil, partial = nil) - details[:locales] = [I18n.locale] - name = name.to_s.gsub(handler_matcher, '').split("/") - find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial) - end - - private - - # This is what child classes implement. No defaults are needed - # because Resolver guarantees that the arguments are present and - # normalized. - def find_templates(name, details, prefix, partial) - raise NotImplementedError - end - - def valid_handlers - @valid_handlers ||= TemplateHandlers.extensions - end - - def handler_matcher - @handler_matcher ||= begin - e = valid_handlers.join('|') - /\.(?:#{e})$/ - end - end - - def handler_glob - e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join - "{#{e}}" - end - - def formats_glob - @formats_glob ||= begin - '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' - end - end - - def cached(key) - return yield unless @cache - return @cached[key] if @cached.key?(key) - @cached[key] = yield - end - end - - class FileSystemResolver < Resolver - - def initialize(path, options = {}) - raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) - super(options) - @path = Pathname.new(path).expand_path - end - - # TODO: This is the currently needed API. Make this suck less - # ==== - attr_reader :path - - def to_s - path.to_s - end - - def to_str - path.to_s - end - - def ==(path) - to_str == path.to_str - end - - def eql?(path) - to_str == path.to_str - end - # ==== - - def find_templates(name, details, prefix, partial, root = "#{@path}/") - if glob = details_to_glob(name, details, prefix, partial, root) - cached(glob) do - Dir[glob].map do |path| - next if File.directory?(path) - source = File.read(path) - identifier = Pathname.new(path).expand_path.to_s - - Template.new(source, identifier, *path_to_details(path)) - end.compact - end - end - end - - private - - # :api: plugin - def details_to_glob(name, details, prefix, partial, root) - path = "" - path << "#{prefix}/" unless prefix.empty? - path << (partial ? "_#{name}" : name) - - extensions = "" - [:locales, :formats].each do |k| - extensions << if exts = details[k] - '{' + exts.map {|e| ".#{e},"}.join + '}' - else - k == :formats ? formats_glob : '' - end - end - - "#{root}#{path}#{extensions}#{handler_glob}" - end - - # TODO: fix me - # :api: plugin - def path_to_details(path) - # [:erb, :format => :html, :locale => :en, :partial => true/false] - if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') - partial = m[1] == '_' - details = (m[2]||"").split('.').reject { |e| e.empty? } - handler = Template.handler_class_for_extension(m[3]) - - format = Mime[details.last] && details.pop.to_sym - locale = details.last && details.pop.to_sym - - return handler, :format => format, :locale => locale, :partial => partial - end - end - end - - class FileSystemResolverWithFallback < FileSystemResolver - - def find_templates(name, details, prefix, partial) - templates = super - return super(name, details, prefix, partial, '') if templates.empty? - templates - end - - end -end \ No newline at end of file diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb new file mode 100644 index 0000000000..d15f53a11b --- /dev/null +++ b/actionpack/lib/action_view/template/resolver.rb @@ -0,0 +1,150 @@ +require "pathname" +require "action_view/template/template" + +module ActionView + # Abstract superclass + class Resolver + def initialize(options) + @cache = options[:cache] + @cached = {} + end + + # Normalizes the arguments and passes it on to find_template + def find_by_parts(*args) + find_all_by_parts(*args).first + end + + def find_all_by_parts(name, details = {}, prefix = nil, partial = nil) + details[:locales] = [I18n.locale] + name = name.to_s.gsub(handler_matcher, '').split("/") + find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial) + end + + private + + # This is what child classes implement. No defaults are needed + # because Resolver guarantees that the arguments are present and + # normalized. + def find_templates(name, details, prefix, partial) + raise NotImplementedError + end + + def valid_handlers + @valid_handlers ||= TemplateHandlers.extensions + end + + def handler_matcher + @handler_matcher ||= begin + e = valid_handlers.join('|') + /\.(?:#{e})$/ + end + end + + def handler_glob + e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join + "{#{e}}" + end + + def formats_glob + @formats_glob ||= begin + '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' + end + end + + def cached(key) + return yield unless @cache + return @cached[key] if @cached.key?(key) + @cached[key] = yield + end + end + + class FileSystemResolver < Resolver + + def initialize(path, options = {}) + raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) + super(options) + @path = Pathname.new(path).expand_path + end + + # TODO: This is the currently needed API. Make this suck less + # ==== + attr_reader :path + + def to_s + path.to_s + end + + def to_str + path.to_s + end + + def ==(path) + to_str == path.to_str + end + + def eql?(path) + to_str == path.to_str + end + # ==== + + def find_templates(name, details, prefix, partial, root = "#{@path}/") + if glob = details_to_glob(name, details, prefix, partial, root) + cached(glob) do + Dir[glob].map do |path| + next if File.directory?(path) + source = File.read(path) + identifier = Pathname.new(path).expand_path.to_s + + Template.new(source, identifier, *path_to_details(path)) + end.compact + end + end + end + + private + + # :api: plugin + def details_to_glob(name, details, prefix, partial, root) + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '{' + exts.map {|e| ".#{e},"}.join + '}' + else + k == :formats ? formats_glob : '' + end + end + + "#{root}#{path}#{extensions}#{handler_glob}" + end + + # TODO: fix me + # :api: plugin + def path_to_details(path) + # [:erb, :format => :html, :locale => :en, :partial => true/false] + if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') + partial = m[1] == '_' + details = (m[2]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[3]) + + format = Mime[details.last] && details.pop.to_sym + locale = details.last && details.pop.to_sym + + return handler, :format => format, :locale => locale, :partial => partial + end + end + end + + class FileSystemResolverWithFallback < FileSystemResolver + + def find_templates(name, details, prefix, partial) + templates = super + return super(name, details, prefix, partial, '') if templates.empty? + templates + end + + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index 53aaa3dded..fac50cd692 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -2,7 +2,7 @@ # This is so that templates compiled in this file are UTF-8 require 'set' -require "action_view/template/path" +require "action_view/template/resolver" module ActionView class Template -- cgit v1.2.3 From 55ee0ba7f5b6b5d2023eb5dcc030946ed589fe53 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 16:23:11 -0700 Subject: Cleaning up if defined?(ActionController::Http) blocks from the pre new base era. --- actionpack/lib/action_view/base.rb | 52 ++++++---------------- actionpack/lib/action_view/render/rendering.rb | 1 - .../lib/action_view/template/handlers/builder.rb | 3 +- 3 files changed, 15 insertions(+), 41 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 2d8f51300a..1ca6f839a8 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -230,39 +230,24 @@ module ActionView #:nodoc: def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: @formats = formats || [:html] @assigns = assigns_for_first_render - @assigns_added = nil @controller = controller @helpers = ProxyModule.new(self) self.view_paths = view_paths - - @_first_render = nil - @_current_render = nil end + attr_internal :template attr_reader :view_paths def view_paths=(paths) @view_paths = self.class.process_view_paths(paths) end - # Access the current template being rendered. - # Returns a ActionView::Template object. - def template - @_current_render - end - - def template=(template) #:nodoc: - @_first_render ||= template - @_current_render = template - end - def with_template(current_template) last_template, self.template = template, current_template - old_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols + last_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols yield ensure - self.template = last_template - self.formats = old_formats + self.template, self.formats = last_template, last_formats end def punctuate_body!(part) @@ -273,30 +258,21 @@ module ActionView #:nodoc: # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: - unless @assigns_added - @assigns.each { |key, value| instance_variable_set("@#{key}", value) } - _copy_ivars_from_controller - @assigns_added = true - end + return if @assigns_added + @assigns.each { |key, value| instance_variable_set("@#{key}", value) } + _copy_ivars_from_controller + @assigns_added = true end - private + private - def _copy_ivars_from_controller #: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 + def _copy_ivars_from_controller #: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 - def _set_controller_content_type(content_type) #:nodoc: - # TODO: Remove this method when new base is switched - unless defined?(ActionController::Http) - if controller.respond_to?(:response) - controller.response.content_type ||= content_type - end - end - end end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index fe785e7b20..d120631e5d 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -64,7 +64,6 @@ module ActionView def _render_template(template, local_assigns = {}) with_template(template) do _evaluate_assigns_and_ivars - _set_controller_content_type(template.mime_type) if template.respond_to?(:mime_type) template.render(self, local_assigns) do |*names| if !instance_variable_defined?(:"@content_for_#{names.first}") && diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb index f412228752..abe140af0b 100644 --- a/actionpack/lib/action_view/template/handlers/builder.rb +++ b/actionpack/lib/action_view/template/handlers/builder.rb @@ -8,8 +8,7 @@ module ActionView self.default_format = Mime::XML def compile(template) - "_set_controller_content_type(Mime::XML);" + - "xml = ::Builder::XmlMarkup.new(:indent => 2);" + + "xml = ::Builder::XmlMarkup.new(:indent => 2);" + "self.output_buffer = xml.target!;" + template.source + ";xml.target!;" -- cgit v1.2.3 From a9ad763c86e110c280be0b7a763496f9e1204de0 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 18:08:45 -0700 Subject: Drive the final stake through @content_for_*'s heart! --- actionpack/lib/action_view/base.rb | 4 ++- .../lib/action_view/helpers/capture_helper.rb | 5 ++-- actionpack/lib/action_view/render/partials.rb | 7 ----- actionpack/lib/action_view/render/rendering.rb | 32 ++++++++++------------ 4 files changed, 19 insertions(+), 29 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 1ca6f839a8..b994c7b141 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -170,12 +170,13 @@ module ActionView #:nodoc: attr_accessor :base_path, :assigns, :template_extension, :formats 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' + delegate :logger, :to => 'ActionController::Base', :allow_nil => true end @@debug_rjs = false @@ -232,6 +233,7 @@ module ActionView #:nodoc: @assigns = assigns_for_first_render @controller = controller @helpers = ProxyModule.new(self) + @_content_for = Hash.new {|h,k| h[k] = "" } self.view_paths = view_paths end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index b4197479a0..1c29eb3b81 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -116,10 +116,9 @@ module ActionView # named @content_for_#{name_of_the_content_block}. The preferred usage is now # <%= yield :footer %>. def content_for(name, content = nil, &block) - ivar = "@content_for_#{name}" content = capture(&block) if block_given? - instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}") - nil + return @_content_for[name] << content if content + @_content_for[name] end # Use an alternate output buffer for the duration of the block. diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index eacf117bea..87314fff67 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -245,13 +245,6 @@ module ActionView end end - def _render_partial_with_block(layout, block, options) - @_proc_for_layout = block - concat(_render_partial(options.merge(:partial => layout))) - ensure - @_proc_for_layout = nil - end - def _render_partial_with_layout(layout, options) if layout prefix = controller && !layout.include?("/") ? controller.controller_path : nil diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index d120631e5d..a720012d1c 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -51,13 +51,12 @@ module ActionView end begin - original_content_for_layout = @content_for_layout if defined?(@content_for_layout) - @content_for_layout = content + old_content, @_content_for[:layout] = @_content_for[:layout], content - @cached_content_for_layout = @content_for_layout + @cached_content_for_layout = @_content_for[:layout] _render_template(layout, locals) ensure - @content_for_layout = original_content_for_layout + @_content_for[:layout] = old_content end end @@ -66,12 +65,11 @@ module ActionView _evaluate_assigns_and_ivars template.render(self, local_assigns) do |*names| - if !instance_variable_defined?(:"@content_for_#{names.first}") && - instance_variable_defined?(:@_proc_for_layout) && (proc = @_proc_for_layout) - capture(*names, &proc) - elsif instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}") - instance_variable_get(ivar) - end + if !@_content_for.key?(names.first) && @_proc_for_layout + capture(*names, &@_proc_for_layout) + elsif content = @_content_for[names.first || :layout] + content + end end end rescue Exception => e @@ -100,20 +98,18 @@ module ActionView end def _render_template_with_layout(template, layout = nil, options = {}, partial = false) - if controller && logger - logger.info("Rendering #{template.identifier}" + - (options[:status] ? " (#{options[:status]})" : '')) - end - + logger && logger.info("Rendering #{template.identifier}#{' (#{options[:status]})' if options[:status]}") + + locals = options[:locals] || {} + content = if partial object = partial unless partial == true _render_partial_object(template, options, object) else - _render_template(template, options[:locals] || {}) + _render_template(template, locals) end - return content unless layout - _render_content_with_layout(content, layout, options[:locals] || {}) + layout ? _render_content_with_layout(content, layout, locals) : content end end end \ No newline at end of file -- cgit v1.2.3 From b4a91db441fa9583df24fb8d3cf0d6906e8359db Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 18:55:10 -0700 Subject: Extract the layout proc into a method, and write documentation explaining what the proc does in various cases. --- .../lib/action_view/helpers/capture_helper.rb | 4 -- actionpack/lib/action_view/render/rendering.rb | 43 +++++++++++++++++++--- 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 1c29eb3b81..a8b5a9dbb9 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -111,10 +111,6 @@ module ActionView # # WARNING: content_for is ignored in caches. So you shouldn't use it # for elements that will be fragment cached. - # - # The deprecated way of accessing a content_for block is to use an instance variable - # named @content_for_#{name_of_the_content_block}. The preferred usage is now - # <%= yield :footer %>. def content_for(name, content = nil, &block) content = capture(&block) if block_given? return @_content_for[name] << content if content diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index a720012d1c..588a64a652 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -60,16 +60,49 @@ module ActionView end end + # You can think of a layout as a method that is called with a block. This method + # returns the block that the layout is called with. If the user calls yield :some_name, + # the block, by default, returns content_for(:some_name). If the user calls yield, + # the default block returns content_for(:layout). + # + # The user can override this default by passing a block to the layout. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do %>Content<% end %> + # + # # The layout + # <% yield %> + # + # In this case, instead of the default block, which would return content_for(:layout), + # this method returns the block that was passed in to render layout, and the response + # would be Content. + # + # Finally, the block can take block arguments, which can be passed in by yield. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do |name| %>Hello <%= customer.name %><% end %> + # + # # The layout + # <% yield Struct.new(:name).new("David") %> + # + # In this case, the layout would receive the block passed into render :layout, + # and the Struct specified in the layout would be passed into the block. The result + # would be Hello David. + def layout_proc(name) + @_default_layout ||= proc { |*names| @_content_for[names.first || :layout] } + !@_content_for.key?(name) && @_proc_for_layout || @_default_layout + end + def _render_template(template, local_assigns = {}) with_template(template) do _evaluate_assigns_and_ivars template.render(self, local_assigns) do |*names| - if !@_content_for.key?(names.first) && @_proc_for_layout - capture(*names, &@_proc_for_layout) - elsif content = @_content_for[names.first || :layout] - content - end + capture(*names, &layout_proc(names.first)) end end rescue Exception => e -- cgit v1.2.3 From 5267addd4f986c89df3d31f35e046abc3b1fbe26 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 17 Jun 2009 19:37:08 -0700 Subject: Use errors[field] instead of errors.on(field) --- .../action_view/helpers/active_record_helper.rb | 59 ++++------------------ 1 file changed, 11 insertions(+), 48 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb index 8b70200654..75cc651968 100644 --- a/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/actionpack/lib/action_view/helpers/active_record_helper.rb @@ -122,9 +122,9 @@ module ActionView options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError') if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && - (errors = obj.errors.on(method)) + (errors = obj.errors[method]) content_tag("div", - "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.is_a?(Array) ? errors.first : errors)}#{options[:append_text]}", + "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}", :class => options[:css_class] ) else @@ -247,59 +247,22 @@ module ActionView end end - alias_method :tag_without_error_wrapping, :tag - def tag(name, options) - if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name)) - else - tag_without_error_wrapping(name, options) - end - end - - alias_method :content_tag_without_error_wrapping, :content_tag - def content_tag(name, value, options) - if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name)) - else - content_tag_without_error_wrapping(name, value, options) - end - end - - alias_method :to_date_select_tag_without_error_wrapping, :to_date_select_tag - def to_date_select_tag(options = {}, html_options = {}) - if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(to_date_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name)) - else - to_date_select_tag_without_error_wrapping(options, html_options) - end - end - - alias_method :to_datetime_select_tag_without_error_wrapping, :to_datetime_select_tag - def to_datetime_select_tag(options = {}, html_options = {}) - if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(to_datetime_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name)) - else - to_datetime_select_tag_without_error_wrapping(options, html_options) + %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)) end + alias_method_chain meth, :error_wrapping end - alias_method :to_time_select_tag_without_error_wrapping, :to_time_select_tag - def to_time_select_tag(options = {}, html_options = {}) - if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(to_time_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name)) + def error_wrapping(html_tag) + if object.respond_to?(:errors) && object.errors.respond_to?(:full_messages) && object.errors[@method_name].any? + Base.field_error_proc.call(html_tag, self) else - to_time_select_tag_without_error_wrapping(options, html_options) + html_tag end end - def error_wrapping(html_tag, has_error) - has_error ? Base.field_error_proc.call(html_tag, self) : html_tag - end - - def error_message - object.errors.on(@method_name) - end - def column_type object.send(:column_for_attribute, @method_name).type end -- cgit v1.2.3 From 497554fd10e8c7efc54a805661907bc39c8fe6e9 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 18 Jun 2009 11:14:44 -0700 Subject: Fix typo --- actionpack/lib/action_view/render/rendering.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 588a64a652..a9a40c099c 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -84,7 +84,7 @@ module ActionView # ==== Example # # # The template - # <% render :layout => "my_layout" do |name| %>Hello <%= customer.name %><% end %> + # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %> # # # The layout # <% yield Struct.new(:name).new("David") %> -- cgit v1.2.3 From 9f7eaea201b2f408d9effbf82f2731957e284adf Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 18 Jun 2009 12:08:50 -0700 Subject: Minor ActionView cleanup --- actionpack/lib/action_view/base.rb | 9 ++++----- actionpack/lib/action_view/render/rendering.rb | 4 +--- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index b994c7b141..45184f58fb 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -230,7 +230,7 @@ module ActionView #:nodoc: def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: @formats = formats || [:html] - @assigns = assigns_for_first_render + @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @controller = controller @helpers = ProxyModule.new(self) @_content_for = Hash.new {|h,k| h[k] = "" } @@ -245,6 +245,7 @@ module ActionView #:nodoc: end def with_template(current_template) + _evaluate_assigns_and_ivars last_template, self.template = template, current_template last_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols yield @@ -260,10 +261,7 @@ module ActionView #:nodoc: # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: - return if @assigns_added - @assigns.each { |key, value| instance_variable_set("@#{key}", value) } - _copy_ivars_from_controller - @assigns_added = true + @assigns_added ||= _copy_ivars_from_controller end private @@ -274,6 +272,7 @@ module ActionView #:nodoc: 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 + true end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index a9a40c099c..162e38c484 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -99,14 +99,12 @@ module ActionView def _render_template(template, local_assigns = {}) with_template(template) do - _evaluate_assigns_and_ivars - template.render(self, local_assigns) do |*names| capture(*names, &layout_proc(names.first)) end end rescue Exception => e - if TemplateError === e + if e.is_a?(TemplateError) e.sub_template_of(template) raise e else -- cgit v1.2.3 From 9cb8c812f2a23ab5653a7888740a014a02c97c18 Mon Sep 17 00:00:00 2001 From: Darragh Curran Date: Sun, 21 Jun 2009 17:05:43 +0100 Subject: Add content_for?(:name) helper to check if content_for(:name) is present [#1311 state:resolved] Signed-off-by: Pratik Naik --- .../lib/action_view/helpers/capture_helper.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index a8b5a9dbb9..c90acc5ac2 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -117,6 +117,28 @@ module ActionView @_content_for[name] end + # content_for? simply checks whether any content has been captured yet using content_for + # Useful to render parts of your layout differently based on what is in your views. + # + # ==== Examples + # + # Perhaps you will use different css in you layout if no content_for :right_column + # + # <%# This is the layout %> + # + # + # My Website + # <%= yield :script %> + # + # + # <%= yield %> + # <%= yield :right_col %> + # + # + def content_for?(name) + @_content_for[name].present? + end + # Use an alternate output buffer for the duration of the block. # Defaults to a new empty string. def with_output_buffer(buf = nil) #:nodoc: -- cgit v1.2.3