From 9de83050d3a4b260d4aeb5d09ec4eb64f913ba64 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 15 Mar 2010 11:58:05 -0700 Subject: Add deprecation notices for <% %>. * The approach is to compile <% %> into a method call that checks whether the value returned from a block is a String. If it is, it concats to the buffer and prints a deprecation warning. * <%= %> uses exactly the same logic to compile the template, which first checks to see whether it's compiling a block. * This should have no impact on other uses of block in templates. For instance, in <% [1,2,3].each do |i| %><%= i %><% end %>, the call to each returns an Array, not a String, so the result is not concatenated * In two cases (#capture and #cache), a String can be returned that should *never* be concatenated. We have temporarily created a String subclass called NonConcattingString which behaves (and is serialized) identically to String, but is not concatenated by the code that handles deprecated <% %> block helpers. Once we remove support for <% %> block helpers, we can remove NonConcattingString. --- actionpack/lib/action_view/template/handlers/erb.rb | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_view/template') diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index ac5902cc0e..705c2bf82e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -8,6 +8,13 @@ module ActionView super(value.to_s) end alias :append= :<< + + def append_if_string=(value) + if value.is_a?(String) && !value.is_a?(NonConcattingString) + ActiveSupport::Deprecation.warn("<% %> style block helpers are deprecated. Please use <%= %>", caller) + self << value + end + end end module Template::Handlers @@ -21,14 +28,24 @@ module ActionView src << "@output_buffer.safe_concat('" << escape_text(text) << "');" end + BLOCK_EXPR = /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + def add_expr_literal(src, code) - if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + if code =~ BLOCK_EXPR src << '@output_buffer.append= ' << code else src << '@output_buffer.append= (' << code << ');' end end + def add_stmt(src, code) + if code =~ BLOCK_EXPR + src << '@output_buffer.append_if_string= ' << code + else + super + end + end + def add_expr_escaped(src, code) src << '@output_buffer.append= ' << escaped_expr(code) << ';' end -- cgit v1.2.3 From 8dd731bc502a07f4fb76eb2706a1f3bca479ef63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Mar 2010 02:08:34 +0100 Subject: Move more normalization up to the lookup context, so it does not have to repeat in every resolver. --- actionpack/lib/action_view/template/resolver.rb | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'actionpack/lib/action_view/template') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index a43597e728..ee13707327 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -14,15 +14,8 @@ module ActionView @cached.clear end - def find(*args) - find_all(*args).first - end - # Normalizes the arguments and passes it on to find_template. def find_all(name, prefix=nil, partial=false, details={}, key=nil) - name, prefix = normalize_name(name, prefix) - details = details.merge(:handlers => default_handlers) - cached(key, prefix, name, partial) do find_templates(name, prefix, partial, details) end @@ -34,10 +27,6 @@ module ActionView @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes end - def default_handlers - Template::Handlers.extensions + [nil] - end - # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. @@ -45,17 +34,6 @@ module ActionView raise NotImplementedError end - # Support legacy foo.erb names even though we now ignore .erb - # as well as incorrectly putting part of the path in the template - # name instead of the prefix. - def normalize_name(name, prefix) - handlers = Template::Handlers.extensions.join('|') - name = name.to_s.gsub(/\.(?:#{handlers})$/, '') - - parts = name.split('/') - return parts.pop, [prefix, *parts].compact.join("/") - end - def cached(key, prefix, name, partial) return yield unless key && caching? scope = @cached[key][prefix][name] @@ -93,7 +71,7 @@ module ActionView query = File.join(@path, path) exts.each do |ext| - query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}' + query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << ',}' end Dir[query].reject { |p| File.directory?(p) }.map do |p| -- cgit v1.2.3 From 191a2f78b1abeb4d3b5b27de83ffe14b833c4c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 18 Mar 2010 12:10:40 +0100 Subject: Sending the partial as info is no longer required. --- actionpack/lib/action_view/template/resolver.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_view/template') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index ee13707327..28cd30a959 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -57,7 +57,7 @@ module ActionView def find_templates(name, prefix, partial, details) path = build_path(name, prefix, partial, details) - query(partial, path, EXTENSION_ORDER.map { |ext| details[ext] }) + query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end def build_path(name, prefix, partial, details) @@ -67,7 +67,7 @@ module ActionView path end - def query(partial, path, exts) + def query(path, exts) query = File.join(@path, path) exts.each do |ext| @@ -77,7 +77,7 @@ module ActionView Dir[query].reject { |p| File.directory?(p) }.map do |p| handler, format = extract_handler_and_format(p) Template.new(File.read(p), File.expand_path(p), handler, - :partial => partial, :virtual_path => path, :format => format) + :virtual_path => path, :format => format) end end -- cgit v1.2.3 From f28d856cece877d1b2f306f54aeb12cce1db1023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 19 Mar 2010 17:20:15 +0100 Subject: Improve performance of the rendering stack by freezing formats as a sign that they shouldn't be further modified. --- actionpack/lib/action_view/template/resolver.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'actionpack/lib/action_view/template') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 28cd30a959..8e8afaa43f 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -1,6 +1,5 @@ require "pathname" require "active_support/core_ext/class" -require "active_support/core_ext/array/wrap" require "action_view/template" module ActionView @@ -57,7 +56,7 @@ module ActionView def find_templates(name, prefix, partial, details) path = build_path(name, prefix, partial, details) - query(path, EXTENSION_ORDER.map { |ext| details[ext] }) + query(path, EXTENSION_ORDER.map { |ext| details[ext] }, details[:formats]) end def build_path(name, prefix, partial, details) @@ -67,7 +66,7 @@ module ActionView path end - def query(path, exts) + def query(path, exts, formats) query = File.join(@path, path) exts.each do |ext| @@ -75,18 +74,24 @@ module ActionView end Dir[query].reject { |p| File.directory?(p) }.map do |p| - handler, format = extract_handler_and_format(p) + handler, format = extract_handler_and_format(p, formats) Template.new(File.read(p), File.expand_path(p), handler, :virtual_path => path, :format => format) end end - def extract_handler_and_format(path) + # Extract handler and formats from path. If a format cannot be a found neither + # from the path, or the handler, we should return the array of formats given + # to the resolver. + def extract_handler_and_format(path, default_formats) pieces = File.basename(path).split(".") pieces.shift - handler = Template.handler_class_for_extension(pieces.pop) - format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym + handler = Template.handler_class_for_extension(pieces.pop) + format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym + format ||= handler.default_format if handler.respond_to?(:default_format) + format ||= default_formats + [handler, format] end end -- cgit v1.2.3 From 9f92563892007c7f42a51ec7926352d50d596579 Mon Sep 17 00:00:00 2001 From: wycats Date: Fri, 19 Mar 2010 11:49:53 -0700 Subject: Eliminate an error from an implicit dependency on AV::Base --- actionpack/lib/action_view/template/error.rb | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view/template') diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb index 648f708d3d..5222ffa89c 100644 --- a/actionpack/lib/action_view/template/error.rb +++ b/actionpack/lib/action_view/template/error.rb @@ -1,6 +1,26 @@ require "active_support/core_ext/enumerable" module ActionView + class ActionViewError < StandardError #:nodoc: + end + + class MissingTemplate < ActionViewError #:nodoc: + attr_reader :path + + def initialize(paths, path, details, partial) + @path = path + display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ") + template_type = if partial + "partial" + elsif path =~ /layouts/i + 'layout' + else + 'template' + end + + super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}") + end + end class Template # The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a # bunch of intimate details and uses it to report a very precise exception message. @@ -73,11 +93,11 @@ module ActionView end def to_s - "\n#{self.class} (#{message}) #{source_location}:\n" + + "\n#{self.class} (#{message}) #{source_location}:\n" + "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n" end - # don't do anything nontrivial here. Any raised exception from here becomes fatal + # don't do anything nontrivial here. Any raised exception from here becomes fatal # (and can't be rescued). def backtrace @backtrace -- cgit v1.2.3