class ActionView::PathResolver
:nodoc:
An abstract class that implements a Resolver with path semantics.
def build_query(path, details)
def build_query(path, details) query = @pattern.dup prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1" query.gsub!(/\:prefix(\/)?/, prefix) partial = escape_entry(path.partial? ? "_#{path.name}" : path.name) query.gsub!(/\:action/, partial) details.each do |ext, variants| query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}") end File.expand_path(query, @path) end
def escape_entry(entry)
def escape_entry(entry) entry.gsub(/[*?{}\[\]]/, '\\\\\\&') end
def extract_handler_and_format_and_variant(path, default_formats)
from the path, or the handler, we should return the array of formats given
Extract handler, formats and variant from path. If a format cannot be found neither
def extract_handler_and_format_and_variant(path, default_formats) pieces = File.basename(path).split(".") pieces.shift extension = pieces.pop unless extension ActiveSupport::Deprecation.warn(<<-MSG.squish) The file #{path} did not specify a template handler. The default is currently ERB, but will change to RAW in the future. MSG end handler = Template.handler_for_extension(extension) format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last format &&= Template::Types[format] [handler, format, variant] end
def find_template_paths(query)
def find_template_paths(query) Dir[query].reject { |filename| File.directory?(filename) || # deals with case-insensitive file systems. !File.fnmatch(query, filename, File::FNM_EXTGLOB) } end
def find_template_paths(query)
def find_template_paths(query) # deals with case-insensitive file systems. sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] } Dir[query].reject { |filename| File.directory?(filename) || !sanitizer[File.dirname(filename)].include?(filename) } end
def find_templates(name, prefix, partial, details, outside_app_allowed = false)
def find_templates(name, prefix, partial, details, outside_app_allowed = false) path = Path.build(name, prefix, partial) query(path, details, details[:formats], outside_app_allowed) end
def initialize(pattern=nil)
def initialize(pattern=nil) @pattern = pattern || DEFAULT_PATTERN super() end
def inside_path?(path, filename)
def inside_path?(path, filename) filename = File.expand_path(filename) path = File.join(path, '') filename.start_with?(path) end
def mtime(p)
def mtime(p) File.mtime(p) end
def query(path, details, formats, outside_app_allowed)
def query(path, details, formats, outside_app_allowed) query = build_query(path, details) template_paths = find_template_paths query template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed template_paths.map { |template| handler, format, variant = extract_handler_and_format_and_variant(template, formats) contents = File.binread(template) Template.new(contents, File.expand_path(template), handler, :virtual_path => path.virtual, :format => format, :variant => variant, :updated_at => mtime(template) ) } end
def reject_files_external_to_app(files)
def reject_files_external_to_app(files) files.reject { |filename| !inside_path?(@path, filename) } end