Class: Roger::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/roger/resolver.rb

Overview

The resolver is here to resolve urls to paths and sometimes vice-versa

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paths) ⇒ Resolver

Returns a new instance of Resolver.



6
7
8
9
10
11
# File 'lib/roger/resolver.rb', line 6

def initialize(paths)
  fail ArgumentError, "Resolver base path can't be nil" if paths.nil?

  # Convert to paths
  @load_paths = [paths].flatten.map { |p| Pathname.new(p) }
end

Instance Attribute Details

#load_pathsObject (readonly)

Returns the value of attribute load_paths.



4
5
6
# File 'lib/roger/resolver.rb', line 4

def load_paths
  @load_paths
end

Instance Method Details

#find_template(url, options = {}) ⇒ Object Also known as: url_to_path

Parameters:

  • url (String)

    The url to resolve to a path

  • options (Hash) (defaults to: {})

    Options

Options Hash (options):

  • :exact_match (true, false)

    Wether or not to match exact paths, this is mainly used in the path_to_url method to match .js, .css, etc files.

  • :preferred_extension (String)

    The part to chop off and re-add to search for more complex double-extensions. (Makes it possible to have context aware partials)



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/roger/resolver.rb', line 21

def find_template(url, options = {})
  options = {
    exact_match: false,
    preferred_extension: "html"
  }.update(options)

  orig_path, _qs, _anch = strip_query_string_and_anchor(url.to_s)

  output = nil

  load_paths.find do |load_path|
    path = File.join(load_path, orig_path)

    # If it's an exact match we're done
    if options[:exact_match] && File.exist?(path)
      output = Pathname.new(path)
    else
      output = find_file_with_extension(path, options[:preferred_extension])
    end
  end

  output
end

#path_to_url(path, relative_to = nil) ⇒ Object

Convert a disk path on file to an url



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/roger/resolver.rb', line 47

def path_to_url(path, relative_to = nil)
  # Find the parent path we're in
  path = Pathname.new(path).realpath
  base = load_paths.find { |lp| path.to_s =~ /\A#{Regexp.escape(lp.realpath.to_s)}/ }

  path = path.relative_path_from(base).cleanpath

  if relative_to
    relative_path_to_url(path, relative_to, base).to_s
  else
    "/#{path}"
  end
end

#strip_query_string_and_anchor(url) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/roger/resolver.rb', line 78

def strip_query_string_and_anchor(url)
  url = url.dup

  # Strip off anchors
  anchor = nil
  url.gsub!(/(#.+)\Z/) do |r|
    anchor = r
    ""
  end

  # Strip off query strings
  query = nil
  url.gsub!(/(\?.+)\Z/) do |r|
    query = r
    ""
  end

  [url, query, anchor]
end

#url_to_relative_url(url, relative_to_path) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/roger/resolver.rb', line 61

def url_to_relative_url(url, relative_to_path)
  # Skip if the url doesn't start with a / (but not with //)
  return false unless url =~ %r{\A/[^/]}

  path, qs, anch = strip_query_string_and_anchor(url)

  # Get disk path
  if true_path =  url_to_path(path, exact_match: true)
    path = path_to_url(true_path, relative_to_path)
    path += qs if qs
    path += anch if anch
    path
  else
    false
  end
end