class ActionView::FileSystemResolver

A resolver that loads files from the filesystem.

Attributes

path[R]

Public Class Methods

new(path) click to toggle source
Calls superclass method
# File lib/action_view/template/resolver.rb, line 92
def initialize(path)
  raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
  @unbound_templates = Concurrent::Map.new
  @path_parser = PathParser.new
  @path = File.expand_path(path)
  super()
end

Public Instance Methods

==(resolver)
Alias for: eql?
clear_cache() click to toggle source
Calls superclass method ActionView::Resolver#clear_cache
# File lib/action_view/template/resolver.rb, line 100
def clear_cache
  @unbound_templates.clear
  @path_parser = PathParser.new
  super
end
eql?(resolver) click to toggle source
# File lib/action_view/template/resolver.rb, line 111
def eql?(resolver)
  self.class.equal?(resolver.class) && to_path == resolver.to_path
end
Also aliased as: ==
to_path()
Alias for: to_s
to_s() click to toggle source
# File lib/action_view/template/resolver.rb, line 106
def to_s
  @path.to_s
end
Also aliased as: to_path

Private Instance Methods

_find_all(name, prefix, partial, details, key, locals) click to toggle source
# File lib/action_view/template/resolver.rb, line 126
def _find_all(name, prefix, partial, details, key, locals)
  requested_details = key || TemplateDetails::Requested.new(**details)
  cache = key ? @unbound_templates : Concurrent::Map.new

  unbound_templates =
    cache.compute_if_absent(TemplatePath.virtual(name, prefix, partial)) do
      path = TemplatePath.build(name, prefix, partial)
      unbound_templates_from_path(path)
    end

  filter_and_sort_by_details(unbound_templates, requested_details).map do |unbound_template|
    unbound_template.bind_locals(locals)
  end
end
build_unbound_template(template) click to toggle source
# File lib/action_view/template/resolver.rb, line 145
def build_unbound_template(template)
  parsed = @path_parser.parse(template.from(@path.size + 1))
  details = parsed.details
  source = source_for_template(template)

  UnboundTemplate.new(
    source,
    template,
    details: details,
    virtual_path: parsed.path.virtual,
  )
end
escape_entry(entry) click to toggle source
# File lib/action_view/template/resolver.rb, line 203
def escape_entry(entry)
  entry.gsub(/[*?{}\[\]]/, '\\\\\\&')
end
filter_and_sort_by_details(templates, requested_details) click to toggle source
# File lib/action_view/template/resolver.rb, line 175
def filter_and_sort_by_details(templates, requested_details)
  filtered_templates = templates.select do |template|
    template.details.matches?(requested_details)
  end

  if filtered_templates.count > 1
    filtered_templates.sort_by! do |template|
      template.details.sort_key_for(requested_details)
    end
  end

  filtered_templates
end
source_for_template(template) click to toggle source
# File lib/action_view/template/resolver.rb, line 141
def source_for_template(template)
  Template::Sources::File.new(template)
end
template_glob(glob) click to toggle source

Safe glob within @path

# File lib/action_view/template/resolver.rb, line 190
def template_glob(glob)
  query = File.join(escape_entry(@path), glob)
  path_with_slash = File.join(@path, "")

  Dir.glob(query).filter_map do |filename|
    filename = File.expand_path(filename)
    next if File.directory?(filename)
    next unless filename.start_with?(path_with_slash)

    filename
  end
end
unbound_templates_from_path(path) click to toggle source
# File lib/action_view/template/resolver.rb, line 158
def unbound_templates_from_path(path)
  if path.name.include?(".")
    return []
  end

  # Instead of checking for every possible path, as our other globs would
  # do, scan the directory for files with the right prefix.
  paths = template_glob("#{escape_entry(path.to_s)}*")

  paths.map do |path|
    build_unbound_template(path)
  end.select do |template|
    # Select for exact virtual path match, including case sensitivity
    template.virtual_path == path.virtual
  end
end