123456789_123456789_123456789_123456789_123456789_

Class: ActionView::FileSystemResolver

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Resolver
Instance Chain:
self, Resolver
Inherits: ActionView::Resolver
Defined in: actionview/lib/action_view/template/resolver.rb

Overview

A resolver that loads files from the filesystem.

Class Attribute Summary

Resolver - Inherited

Class Method Summary

Instance Attribute Summary

Resolver - Inherited

Instance Method Summary

Constructor Details

.new(path) ⇒ FileSystemResolver

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 93

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

Instance Attribute Details

#path (readonly)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 91

attr_reader :path

Instance Method Details

#==(resolver)

Alias for #eql?.

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 115

alias :== :eql?

#_find_all(name, prefix, partial, details, key, locals) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 131

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

#all_template_paths

This method is for internal use only.
[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 117

def all_template_paths # :nodoc:
  paths = template_glob("**/*")
  paths.map do |filename|
    filename.from(@path.size + 1).remove(/\.[^\/]*\z/)
  end.uniq.map do |filename|
    TemplatePath.parse(filename)
  end
end

#build_unbound_template(template) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 150

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

#built_templates

This method is for internal use only.
[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 126

def built_templates # :nodoc:
  @unbound_templates.values.flatten.flat_map(&:built_templates)
end

#clear_cache

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 101

def clear_cache
  @unbound_templates.clear
  @path_parser = PathParser.new
  super
end

#eql?(resolver) ⇒ Boolean Also known as: #==

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 112

def eql?(resolver)
  self.class.equal?(resolver.class) && to_path == resolver.to_path
end

#escape_entry(entry) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 208

def escape_entry(entry)
  entry.gsub(/[*?{}\[\]]/, '\\\\\\&')
end

#filter_and_sort_by_details(templates, requested_details) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 180

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) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 146

def source_for_template(template)
  Template::Sources::File.new(template)
end

#template_glob(glob) (private)

Safe glob within @path

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 195

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

#to_path

Alias for #to_s.

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 110

alias :to_path :to_s

#to_s Also known as: #to_path

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 107

def to_s
  @path.to_s
end

#unbound_templates_from_path(path) (private)

[ GitHub ]

  
# File 'actionview/lib/action_view/template/resolver.rb', line 163

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