aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/template_file.rb
blob: c38e8ed1222a3be33d342dfd62d62ec2f8a4e4e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module ActionView #:nodoc:
  # TemplateFile abstracts the pattern of querying a file path for its
  # path with or without its extension. The path is only the partial path
  # from the load path root e.g. "hello/index.html.erb" not
  # "app/views/hello/index.html.erb"
  class TemplateFile
    def self.from_path(path)
      path.is_a?(self) ? path : new(path)
    end

    def self.from_full_path(load_path, full_path)
      file = new(full_path.split(load_path).last)
      file.load_path = load_path
      file.freeze
    end

    attr_accessor :load_path, :base_path, :name, :format, :extension
    delegate :to_s, :inspect, :to => :path

    def initialize(path)
      path = path.dup

      # Clear the forward slash in the beginning
      trim_forward_slash!(path)

      @base_path, @name, @format, @extension = split(path)
    end

    def freeze
      @load_path.freeze
      @base_path.freeze
      @name.freeze
      @format.freeze
      @extension.freeze
      super
    end

    def format_and_extension
      extensions = [format, extension].compact.join(".")
      extensions.blank? ? nil : extensions
    end

    def full_path
      if load_path
        "#{load_path}/#{path}"
      else
        path
      end
    end

    def path
      base_path.to_s + [name, format, extension].compact.join(".")
    end

    def path_without_extension
      base_path.to_s + [name, format].compact.join(".")
    end

    def path_without_format_and_extension
      "#{base_path}#{name}"
    end

    def dup_with_extension(extension)
      file = dup
      file.extension = extension ? extension.to_s : nil
      file
    end

    private
      def trim_forward_slash!(path)
        path.sub!(/^\//, '')
      end

      # Returns file split into an array
      #   [base_path, name, format, extension]
      def split(file)
        if m = file.match(/^(.*\/)?(\w+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
          if m[5] # Mulipart formats
            [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
          elsif m[4] # Single format
            [m[1], m[2], m[3], m[4]]
          else # No format
            [m[1], m[2], nil, m[3]]
          end
        end
      end
  end
end