aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/template
diff options
context:
space:
mode:
authorCarlhuda <carlhuda@engineyard.com>2009-12-02 20:01:01 -0800
committerCarlhuda <carlhuda@engineyard.com>2009-12-02 20:01:08 -0800
commitc1304098cca8a9247a9ad1461a1a343354650843 (patch)
tree41bd12bcca3ce2062b10c043663a72662796cbd1 /actionpack/lib/action_view/template
parent399909b11c094ab32542d300c72940b1b263b8e6 (diff)
downloadrails-c1304098cca8a9247a9ad1461a1a343354650843.tar.gz
rails-c1304098cca8a9247a9ad1461a1a343354650843.tar.bz2
rails-c1304098cca8a9247a9ad1461a1a343354650843.zip
Reorganize autoloads:
* A new module (ActiveSupport::Autoload) is provide that extends autoloading with new behavior. * All autoloads in modules that have extended ActiveSupport::Autoload will be eagerly required in threadsafe environments * Autoloads can optionally leave off the path if the path is the same as full_constant_name.underscore * It is possible to specify that a group of autoloads live under an additional path. For instance, all of ActionDispatch's middlewares are ActionDispatch::MiddlewareName, but they live under "action_dispatch/middlewares/middleware_name" * It is possible to specify that a group of autoloads are all found at the same path. For instance, a number of exceptions might all be declared there. * One consequence of this is that testing-related constants are not autoloaded. To get the testing helpers for a given component, require "component_name/test_case". For instance, "action_controller/test_case". * test_help.rb, which is automatically required by a Rails application's test helper, requires the test_case.rb for all active components, so this change will not be disruptive in existing or new applications.
Diffstat (limited to 'actionpack/lib/action_view/template')
-rw-r--r--actionpack/lib/action_view/template/error.rb152
-rw-r--r--actionpack/lib/action_view/template/handler.rb47
-rw-r--r--actionpack/lib/action_view/template/handlers.rb96
-rw-r--r--actionpack/lib/action_view/template/handlers/builder.rb4
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb4
-rw-r--r--actionpack/lib/action_view/template/handlers/rjs.rb4
-rw-r--r--actionpack/lib/action_view/template/resolver.rb6
-rw-r--r--actionpack/lib/action_view/template/template.rb131
-rw-r--r--actionpack/lib/action_view/template/text.rb70
9 files changed, 197 insertions, 317 deletions
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index aa21606f76..a136d4333b 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -1,101 +1,103 @@
require "active_support/core_ext/enumerable"
module ActionView
- # The TemplateError 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.
- class TemplateError < ActionViewError #:nodoc:
- SOURCE_CODE_RADIUS = 3
+ 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.
+ class Error < ActionViewError #:nodoc:
+ SOURCE_CODE_RADIUS = 3
- attr_reader :original_exception
+ attr_reader :original_exception
- def initialize(template, assigns, original_exception)
- @template, @assigns, @original_exception = template, assigns.dup, original_exception
- @backtrace = compute_backtrace
- end
+ def initialize(template, assigns, original_exception)
+ @template, @assigns, @original_exception = template, assigns.dup, original_exception
+ @backtrace = compute_backtrace
+ end
- def file_name
- @template.identifier
- end
+ def file_name
+ @template.identifier
+ end
- def message
- ActiveSupport::Deprecation.silence { original_exception.message }
- end
+ def message
+ ActiveSupport::Deprecation.silence { original_exception.message }
+ end
- def clean_backtrace
- if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
- Rails.backtrace_cleaner.clean(original_exception.backtrace)
- else
- original_exception.backtrace
+ def clean_backtrace
+ if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
+ Rails.backtrace_cleaner.clean(original_exception.backtrace)
+ else
+ original_exception.backtrace
+ end
end
- end
- def sub_template_message
- if @sub_templates
- "Trace of template inclusion: " +
- @sub_templates.collect { |template| template.inspect }.join(", ")
- else
- ""
+ def sub_template_message
+ if @sub_templates
+ "Trace of template inclusion: " +
+ @sub_templates.collect { |template| template.inspect }.join(", ")
+ else
+ ""
+ end
end
- end
- def source_extract(indentation = 0)
- return unless num = line_number
- num = num.to_i
+ def source_extract(indentation = 0)
+ return unless num = line_number
+ num = num.to_i
- source_code = @template.source.split("\n")
+ source_code = @template.source.split("\n")
- start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
- end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
+ start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
+ end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
- indent = ' ' * indentation
- line_counter = start_on_line
- return unless source_code = source_code[start_on_line..end_on_line]
+ indent = ' ' * indentation
+ line_counter = start_on_line
+ return unless source_code = source_code[start_on_line..end_on_line]
- source_code.sum do |line|
- line_counter += 1
- "#{indent}#{line_counter}: #{line}\n"
+ source_code.sum do |line|
+ line_counter += 1
+ "#{indent}#{line_counter}: #{line}\n"
+ end
end
- end
- def sub_template_of(template_path)
- @sub_templates ||= []
- @sub_templates << template_path
- end
-
- def line_number
- @line_number ||=
- if file_name
- regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
-
- $1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
- end
- end
+ def sub_template_of(template_path)
+ @sub_templates ||= []
+ @sub_templates << template_path
+ end
- def to_s
- "\n#{self.class} (#{message}) #{source_location}:\n" +
- "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
- end
+ def line_number
+ @line_number ||=
+ if file_name
+ regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
- # don't do anything nontrivial here. Any raised exception from here becomes fatal
- # (and can't be rescued).
- def backtrace
- @backtrace
- end
+ $1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
+ end
+ end
- private
- def compute_backtrace
- [
- "#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
- clean_backtrace.join("\n ")
- ]
+ def to_s
+ "\n#{self.class} (#{message}) #{source_location}:\n" +
+ "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
end
- def source_location
- if line_number
- "on line ##{line_number} of "
- else
- 'in '
- end + file_name
+ # don't do anything nontrivial here. Any raised exception from here becomes fatal
+ # (and can't be rescued).
+ def backtrace
+ @backtrace
end
+
+ private
+ def compute_backtrace
+ [
+ "#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
+ clean_backtrace.join("\n ")
+ ]
+ end
+
+ def source_location
+ if line_number
+ "on line ##{line_number} of "
+ else
+ 'in '
+ end + file_name
+ end
+ end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/handler.rb b/actionpack/lib/action_view/template/handler.rb
index 4bf58b9fa8..5a46a27893 100644
--- a/actionpack/lib/action_view/template/handler.rb
+++ b/actionpack/lib/action_view/template/handler.rb
@@ -3,34 +3,39 @@ require "action_dispatch/http/mime_type"
# Legacy TemplateHandler stub
module ActionView
- module TemplateHandlers #:nodoc:
- module Compilable
- def self.included(base)
- base.extend(ClassMethods)
- end
+ class Template
+ module Handlers #:nodoc:
+ module Compilable
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
- module ClassMethods
- def call(template)
- new.compile(template)
+ module ClassMethods
+ def call(template)
+ new.compile(template)
+ end
end
- end
- def compile(template)
- raise "Need to implement #{self.class.name}#compile(template)"
- end
+ def compile(template)
+ raise "Need to implement #{self.class.name}#compile(template)"
+ end
+ end
end
- end
- class TemplateHandler
- extlib_inheritable_accessor :default_format
- self.default_format = Mime::HTML
+ class Template::Handler
+ extlib_inheritable_accessor :default_format
+ self.default_format = Mime::HTML
- def self.call(template)
- raise "Need to implement #{self.class.name}#call(template)"
- end
+ def self.call(template)
+ raise "Need to implement #{self.class.name}#call(template)"
+ end
- def render(template, local_assigns)
- raise "Need to implement #{self.class.name}#render(template, local_assigns)"
+ def render(template, local_assigns)
+ raise "Need to implement #{self.class.name}#render(template, local_assigns)"
+ end
end
end
+
+ TemplateHandlers = Template::Handlers
+ TemplateHandler = Template::Handler
end
diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb
index faf54b9fe5..35488c0391 100644
--- a/actionpack/lib/action_view/template/handlers.rb
+++ b/actionpack/lib/action_view/template/handlers.rb
@@ -1,52 +1,54 @@
module ActionView #:nodoc:
- module TemplateHandlers #:nodoc:
- autoload :ERB, 'action_view/template/handlers/erb'
- autoload :RJS, 'action_view/template/handlers/rjs'
- autoload :Builder, 'action_view/template/handlers/builder'
-
- def self.extended(base)
- base.register_default_template_handler :erb, TemplateHandlers::ERB
- base.register_template_handler :rjs, TemplateHandlers::RJS
- base.register_template_handler :builder, TemplateHandlers::Builder
-
- # TODO: Depreciate old template extensions
- base.register_template_handler :rhtml, TemplateHandlers::ERB
- base.register_template_handler :rxml, TemplateHandlers::Builder
- end
-
- @@template_handlers = {}
- @@default_template_handlers = nil
+ class Template
+ module Handlers #:nodoc:
+ autoload :ERB, 'action_view/template/handlers/erb'
+ autoload :RJS, 'action_view/template/handlers/rjs'
+ autoload :Builder, 'action_view/template/handlers/builder'
+
+ def self.extended(base)
+ base.register_default_template_handler :erb, ERB
+ base.register_template_handler :rjs, RJS
+ base.register_template_handler :builder, Builder
+
+ # TODO: Depreciate old template extensions
+ base.register_template_handler :rhtml, ERB
+ base.register_template_handler :rxml, Builder
+ end
+
+ @@template_handlers = {}
+ @@default_template_handlers = nil
- def self.extensions
- @@template_handlers.keys
- end
-
- # Register a class that knows how to handle template files with the given
- # extension. This can be used to implement new template types.
- # The constructor for the class must take the ActiveView::Base instance
- # as a parameter, and the class must implement a +render+ method that
- # takes the contents of the template to render as well as the Hash of
- # local assigns available to the template. The +render+ method ought to
- # return the rendered template as a string.
- def register_template_handler(extension, klass)
- @@template_handlers[extension.to_sym] = klass
- end
-
- def template_handler_extensions
- @@template_handlers.keys.map {|key| key.to_s }.sort
- end
-
- def registered_template_handler(extension)
- extension && @@template_handlers[extension.to_sym]
- end
-
- def register_default_template_handler(extension, klass)
- register_template_handler(extension, klass)
- @@default_template_handlers = klass
- end
-
- def handler_class_for_extension(extension)
- (extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
+ def self.extensions
+ @@template_handlers.keys
+ end
+
+ # Register a class that knows how to handle template files with the given
+ # extension. This can be used to implement new template types.
+ # The constructor for the class must take the ActiveView::Base instance
+ # as a parameter, and the class must implement a +render+ method that
+ # takes the contents of the template to render as well as the Hash of
+ # local assigns available to the template. The +render+ method ought to
+ # return the rendered template as a string.
+ def register_template_handler(extension, klass)
+ @@template_handlers[extension.to_sym] = klass
+ end
+
+ def template_handler_extensions
+ @@template_handlers.keys.map {|key| key.to_s }.sort
+ end
+
+ def registered_template_handler(extension)
+ extension && @@template_handlers[extension.to_sym]
+ end
+
+ def register_default_template_handler(extension, klass)
+ register_template_handler(extension, klass)
+ @@default_template_handlers = klass
+ end
+
+ def handler_class_for_extension(extension)
+ (extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
+ end
end
end
end
diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb
index 5f381f7bf0..a93cfca8aa 100644
--- a/actionpack/lib/action_view/template/handlers/builder.rb
+++ b/actionpack/lib/action_view/template/handlers/builder.rb
@@ -1,6 +1,6 @@
module ActionView
- module TemplateHandlers
- class Builder < TemplateHandler
+ module Template::Handlers
+ class Builder < Template::Handler
include Compilable
self.default_format = Mime::XML
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index 88aeb4b053..f8e6376589 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/string/output_safety'
require 'erubis'
module ActionView
- module TemplateHandlers
+ module Template::Handlers
class Erubis < ::Erubis::Eruby
def add_preamble(src)
src << "@output_buffer = ActionView::SafeBuffer.new;"
@@ -26,7 +26,7 @@ module ActionView
end
end
- class ERB < TemplateHandler
+ class ERB < Template::Handler
include Compilable
##
diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb
index b1d15dc209..63e7dc0902 100644
--- a/actionpack/lib/action_view/template/handlers/rjs.rb
+++ b/actionpack/lib/action_view/template/handlers/rjs.rb
@@ -1,6 +1,6 @@
module ActionView
- module TemplateHandlers
- class RJS < TemplateHandler
+ module Template::Handlers
+ class RJS < Template::Handler
include Compilable
self.default_format = Mime::JS
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 7336114e1b..a2f4ab2ef5 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -1,6 +1,6 @@
require "pathname"
require "active_support/core_ext/class"
-require "action_view/template/template"
+require "action_view/template"
module ActionView
# Abstract superclass
@@ -20,7 +20,7 @@ module ActionView
register_detail(:locale) { [I18n.locale] }
register_detail(:formats) { Mime::SET.symbols }
register_detail(:handlers, :allow_nil => false) do
- TemplateHandlers.extensions
+ Template::Handlers.extensions
end
def initialize(options = {})
@@ -65,7 +65,7 @@ module ActionView
# as well as incorrectly putting part of the path in the template
# name instead of the prefix.
def normalize_name(name, prefix)
- handlers = TemplateHandlers.extensions.join('|')
+ handlers = Template::Handlers.extensions.join('|')
name = name.to_s.gsub(/\.(?:#{handlers})$/, '')
parts = name.split('/')
diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb
deleted file mode 100644
index d1970ca3c7..0000000000
--- a/actionpack/lib/action_view/template/template.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-# encoding: utf-8
-# This is so that templates compiled in this file are UTF-8
-
-require 'set'
-require "action_view/template/resolver"
-
-module ActionView
- class Template
- extend TemplateHandlers
- attr_reader :source, :identifier, :handler, :mime_type, :formats, :details
-
- def initialize(source, identifier, handler, details)
- @source = source
- @identifier = identifier
- @handler = handler
- @details = details
- @method_names = {}
-
- format = details.delete(:format) || begin
- # TODO: Clean this up
- handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
- end
- @mime_type = Mime::Type.lookup_by_extension(format.to_s)
- @formats = [format.to_sym]
- @formats << :html if format == :js
- @details[:formats] = Array.wrap(format.to_sym)
- end
-
- def render(view, locals, &block)
- ActiveSupport::Notifications.instrument(:render_template, :identifier => identifier) do
- method_name = compile(locals, view)
- view.send(method_name, locals, &block)
- end
- rescue Exception => e
- if e.is_a?(TemplateError)
- e.sub_template_of(self)
- raise e
- else
- raise TemplateError.new(self, view.assigns, e)
- end
- end
-
- # TODO: Figure out how to abstract this
- def variable_name
- @variable_name ||= identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym
- end
-
- # TODO: Figure out how to abstract this
- def counter_name
- @counter_name ||= "#{variable_name}_counter".to_sym
- end
-
- # TODO: kill hax
- def partial?
- @details[:partial]
- end
-
- def inspect
- if defined?(Rails.root)
- identifier.sub("#{Rails.root}/", '')
- else
- identifier
- end
- end
-
- private
- def compile(locals, view)
- method_name = build_method_name(locals)
-
- return method_name if view.respond_to?(method_name)
-
- locals_code = locals.keys.map! { |key| "#{key} = local_assigns[:#{key}];" }.join
-
- code = @handler.call(self)
- if code.sub!(/\A(#.*coding.*)\n/, '')
- encoding_comment = $1
- elsif defined?(Encoding) && Encoding.respond_to?(:default_external)
- encoding_comment = "#coding:#{Encoding.default_external}"
- end
-
- source = <<-end_src
- def #{method_name}(local_assigns)
- old_output_buffer = output_buffer;#{locals_code};#{code}
- ensure
- self.output_buffer = old_output_buffer
- end
- end_src
-
- if encoding_comment
- source = "#{encoding_comment}\n#{source}"
- line = -1
- else
- line = 0
- end
-
- begin
- ActionView::CompiledTemplates.module_eval(source, identifier, line)
- method_name
- rescue Exception => e # errors from template code
- if logger = (view && view.logger)
- logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
- logger.debug "Function body: #{source}"
- logger.debug "Backtrace: #{e.backtrace.join("\n")}"
- end
-
- raise ActionView::TemplateError.new(self, {}, e)
- end
- end
-
- class LocalsKey
- @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } }
-
- def self.get(*locals)
- @hash_keys[*locals] ||= new(klass, format, locale)
- end
-
- attr_accessor :hash
- def initialize(klass, format, locale)
- @hash = locals.hash
- end
-
- alias_method :eql?, :equal?
- end
-
- def build_method_name(locals)
- # TODO: is locals.keys.hash reliably the same?
- @method_names[locals.keys.hash] ||=
- "_render_template_#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
- end
- end
-end
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index f6e011a5ab..67e086d8bd 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -1,38 +1,40 @@
module ActionView #:nodoc:
- class TextTemplate < String #:nodoc:
- HTML = Mime[:html]
-
- def initialize(string, content_type = HTML)
- super(string.to_s)
- @content_type = Mime[content_type] || content_type
- end
-
- def details
- {:formats => [@content_type.to_sym]}
- end
-
- def identifier
- self
- end
-
- def inspect
- 'text template'
- end
-
- def render(*args)
- to_s
- end
-
- def mime_type
- @content_type
- end
-
- def formats
- [mime_type]
- end
-
- def partial?
- false
+ class Template
+ class Text < String #:nodoc:
+ HTML = Mime[:html]
+
+ def initialize(string, content_type = HTML)
+ super(string.to_s)
+ @content_type = Mime[content_type] || content_type
+ end
+
+ def details
+ {:formats => [@content_type.to_sym]}
+ end
+
+ def identifier
+ self
+ end
+
+ def inspect
+ 'text template'
+ end
+
+ def render(*args)
+ to_s
+ end
+
+ def mime_type
+ @content_type
+ end
+
+ def formats
+ [mime_type]
+ end
+
+ def partial?
+ false
+ end
end
end
end