aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/template.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view/template.rb')
-rw-r--r--actionpack/lib/action_view/template.rb128
1 files changed, 65 insertions, 63 deletions
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index 4c3f252c10..304aec3a4c 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -1,94 +1,96 @@
module ActionView #:nodoc:
- class Template #:nodoc:
+ class Template
extend TemplateHandlers
+ include ActiveSupport::Memoizable
+ include Renderable
- attr_accessor :locals
- attr_reader :handler, :path, :extension, :filename, :method
+ attr_accessor :filename, :load_path, :base_path, :name, :format, :extension
+ delegate :to_s, :to => :path
- def initialize(view, path, use_full_path, locals = {})
- @view = view
- @paths = view.view_paths
+ def initialize(template_path, load_paths = [])
+ template_path = template_path.dup
+ @base_path, @name, @format, @extension = split(template_path)
+ @base_path.to_s.gsub!(/\/$/, '') # Push to split method
+ @load_path, @filename = find_full_path(template_path, load_paths)
- @original_path = path
- @path = TemplateFile.from_path(path, !use_full_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)
-
- @locals = locals || {}
- @handler = self.class.handler_class_for_extension(@extension).new(@view)
+ # Extend with partial super powers
+ extend RenderablePartial if @name =~ /^_/
end
- def render_template
- render
- rescue Exception => e
- raise e unless filename
- if TemplateError === e
- e.sub_template_of(filename)
- raise e
- else
- raise TemplateError.new(self, @view.assigns, e)
- end
+ def format_and_extension
+ (extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
end
+ memoize :format_and_extension
- def render
- prepare!
- @handler.render(self)
+ def path
+ [base_path, [name, format, extension].compact.join('.')].compact.join('/')
end
+ memoize :path
def path_without_extension
- @path.path_without_extension
+ [base_path, [name, format].compact.join('.')].compact.join('/')
end
+ memoize :path_without_extension
- def source
- @source ||= File.read(self.filename)
+ def path_without_format_and_extension
+ [base_path, name].compact.join('/')
end
+ memoize :path_without_format_and_extension
- def method_key
- @filename
+ def source
+ File.read(filename)
end
+ memoize :source
- def base_path_for_exception
- (@paths.find_load_path_for_path(@path) || @paths.first).to_s
+ def method_segment
+ segment = File.expand_path(filename)
+ segment.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}/, '') if defined?(RAILS_ROOT)
+ segment.gsub!(/([^a-zA-Z0-9_])/) { $1.ord }
end
+ memoize :method_segment
- 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
+ def render_template(view, local_assigns = {})
+ render(view, local_assigns)
+ rescue Exception => e
+ raise e unless filename
+ if TemplateError === e
+ e.sub_template_of(filename)
+ raise e
+ else
+ raise TemplateError.new(self, view.assigns, e)
end
end
private
- def set_extension_and_file_name(use_full_path)
- @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
+ def valid_extension?(extension)
+ Template.template_handler_extensions.include?(extension)
+ end
- if @path = @paths.find_template_file_for_path(path)
- @filename = @path.full_path
- @extension = @path.extension
- end
- else
- @filename = @path.full_path
+ def find_full_path(path, load_paths)
+ load_paths = Array(load_paths) + [nil]
+ load_paths.each do |load_path|
+ file = [load_path, path].compact.join('/')
+ return load_path, file if File.exist?(file)
end
-
- raise_missing_template_exception if @filename.blank?
+ raise MissingTemplate.new(load_paths, path)
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}")
+ # Returns file split into an array
+ # [base_path, name, format, extension]
+ def split(file)
+ if m = file.match(/^(.*\/)?([^\.]+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
+ if m[5] # Mulipart formats
+ [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
+ elsif m[4] # Single format
+ [m[1], m[2], m[3], m[4]]
+ else
+ if valid_extension?(m[3]) # No format
+ [m[1], m[2], nil, m[3]]
+ else # No extension
+ [m[1], m[2], m[3], nil]
+ end
+ end
+ end
end
end
end