Class: ActionView::TemplateFinder

Inherits:
Object
  • Object
show all
Defined in:
lib/action_view/template_finder.rb

Overview

:nodoc:

Defined Under Namespace

Classes: InvalidViewPath

Constant Summary collapse

@@processed_view_paths =
Hash.new {|hash, key| hash[key] = []}
@@file_extension_cache =
Hash.new {|hash, key|
  hash[key] = Hash.new {|hash, key| hash[key] = []}
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ TemplateFinder

Returns a new instance of TemplateFinder.



74
75
76
77
78
79
80
# File 'lib/action_view/template_finder.rb', line 74

def initialize(*args)
  @template = args.shift

  @view_paths = args.flatten
  @view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact
  check_view_paths(@view_paths)
end

Instance Attribute Details

#view_pathsObject

Returns the value of attribute view_paths.



72
73
74
# File 'lib/action_view/template_finder.rb', line 72

def view_paths
  @view_paths
end

Class Method Details

.process_view_paths(*view_paths) ⇒ Object

This method is not thread safe. Mutex should be used whenever this is accessed from an instance method



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/action_view/template_finder.rb', line 23

def process_view_paths(*view_paths)
  view_paths.flatten.compact.each do |dir|
    next if @@processed_view_paths.has_key?(dir)
    @@processed_view_paths[dir] = []
    
    # 
    # Dir.glob("#{dir}/**/*/**") reads all the directories in view path and templates inside those directories
    # Dir.glob("#{dir}/**") reads templates residing at top level of view path
    # 
    (Dir.glob("#{dir}/**/*/**") | Dir.glob("#{dir}/**")).each do |file|
      unless File.directory?(file)
        @@processed_view_paths[dir] << file.split(dir).last.sub(/^\//, '')

        # Build extension cache
        extension = file.split(".").last
        if template_handler_extensions.include?(extension)
          key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
          @@file_extension_cache[dir][key] << extension
        end
      end
    end
  end
end

.reload!Object



60
61
62
63
64
65
66
67
68
69
# File 'lib/action_view/template_finder.rb', line 60

def reload!
  view_paths = @@processed_view_paths.keys

  @@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
  @@file_extension_cache = Hash.new {|hash, key|
    hash[key] = Hash.new {|hash, key| hash[key] = []}
  }

  process_view_paths(view_paths)
end

.template_handler_extensionsObject



56
57
58
# File 'lib/action_view/template_finder.rb', line 56

def template_handler_extensions
  ActionView::Template.template_handler_extensions
end

.update_extension_cache_for(extension) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/action_view/template_finder.rb', line 47

def update_extension_cache_for(extension)
  @@processed_view_paths.keys.each do |dir|
    Dir.glob("#{dir}/**/*.#{extension}").each do |file|
      key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
      @@file_extension_cache[dir][key] << extension
    end
  end
end

Instance Method Details

#append_view_path(path) ⇒ Object



88
89
90
91
92
# File 'lib/action_view/template_finder.rb', line 88

def append_view_path(path)
  @view_paths.push(*path)

  self.class.process_view_paths(path)
end

#extract_base_path_from(full_path) ⇒ Object

Returns the view path that the full path resides in.



124
125
126
# File 'lib/action_view/template_finder.rb', line 124

def extract_base_path_from(full_path)
  @view_paths.find { |p| full_path[0..p.size - 1] == p }
end

#file_exists?(template_path) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/action_view/template_finder.rb', line 106

def file_exists?(template_path)
  # Clear the forward slash in the beginning if exists
  template_path = template_path.sub(/^\//, '')

  template_file_name, template_file_extension = path_and_extension(template_path)

  if template_file_extension
    template_exists?(template_file_name, template_file_extension)
  else
    template_exists?(template_file_name, pick_template_extension(template_path))
  end
end

#find_base_path_for(template_file_name) ⇒ Object



119
120
121
# File 'lib/action_view/template_finder.rb', line 119

def find_base_path_for(template_file_name)
  @view_paths.find { |path| @@processed_view_paths[path].include?(template_file_name) }
end

#find_template_extension_from_first_renderObject

Determine the template extension from the @first_render filename



166
167
168
# File 'lib/action_view/template_finder.rb', line 166

def find_template_extension_from_first_render
  File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1]
end

#find_template_extension_from_handler(template_path, template_format = @template.template_format) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/action_view/template_finder.rb', line 146

def find_template_extension_from_handler(template_path, template_format = @template.template_format)
  formatted_template_path = "#{template_path}.#{template_format}"

  view_paths.each do |path|
    if (extensions = @@file_extension_cache[path][formatted_template_path]).any?
      return "#{template_format}.#{extensions.first}"
    elsif (extensions = @@file_extension_cache[path][template_path]).any?
      return extensions.first.to_s
    end
  end
  nil
end

#path_and_extension(template_path) ⇒ Object

Splits the path and extension from the given template_path and returns as an array.



160
161
162
163
# File 'lib/action_view/template_finder.rb', line 160

def path_and_extension(template_path)
  template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
  [ template_path_without_extension, $1 ]
end

#pick_template(template_path, extension) ⇒ Object Also known as: template_exists?



99
100
101
102
103
# File 'lib/action_view/template_finder.rb', line 99

def pick_template(template_path, extension)
  file_name = "#{template_path}.#{extension}"
  base_path = find_base_path_for(file_name)
  base_path.blank? ? false : "#{base_path}/#{file_name}"
end

#pick_template_extension(template_path) ⇒ Object

Gets the extension for an existing template with the given template_path. Returns the format with the extension if that template exists.

pick_template_extension('users/show')
# => 'html.erb'

pick_template_extension('users/legacy')
# => "rhtml"


137
138
139
140
141
142
143
144
# File 'lib/action_view/template_finder.rb', line 137

def pick_template_extension(template_path)
  if extension = find_template_extension_from_handler(template_path, @template.template_format) || find_template_extension_from_first_render
    extension
  elsif @template.template_format == :js && extension = find_template_extension_from_handler(template_path, :html)
    @template.template_format = :html
    extension
  end
end

#prepend_view_path(path) ⇒ Object



82
83
84
85
86
# File 'lib/action_view/template_finder.rb', line 82

def prepend_view_path(path)
  @view_paths.unshift(*path)

  self.class.process_view_paths(path)
end