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, candidates| if ext == :variants && candidates == :any query.gsub!(/:#{ext}/, "*") else query.gsub!(/:#{ext}/, "{#{candidates.compact.uniq.join(',')}}") end end File.expand_path(query, @path) end
def escape_entry(entry)
def escape_entry(entry) entry.gsub(/[*?{}\[\]]/, '\\\\\\&'.freeze) end
def extract_handler_and_format_and_variant(path)
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) pieces = File.basename(path).split(".".freeze) pieces.shift extension = pieces.pop 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].uniq.reject do |filename| File.directory?(filename) || # deals with case-insensitive file systems. !File.fnmatch(query, filename, File::FNM_EXTGLOB) end 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 do |template| handler, format, variant = extract_handler_and_format_and_variant(template) 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 end
def reject_files_external_to_app(files)
def reject_files_external_to_app(files) files.reject { |filename| !inside_path?(@path, filename) } end