class Roadie::UrlGenerator

@api private Class that handles URL generation

URL generation is all about converting relative URLs into absolute URLS according to the given options. It is written such as absolute URLs will get passed right through, so all URLs could be passed through here.

Constants

VALID_OPTIONS

Attributes

root_uri[R]
scheme[R]
url_options[R]

Public Class Methods

new(url_options) click to toggle source

Create a new instance with the given URL options.

Initializing without a host setting raises an error, as do unknown keys.

@param [Hash] #url_options @option #url_options [String] :host (required) @option #url_options [String, Integer] :port @option #url_options [String] :path root path @option #url_options [String] :scheme URL scheme (“http” is default) @option #url_options [String] :protocol alias for :scheme

# File lib/roadie/url_generator.rb, line 23
def initialize(url_options)
  raise ArgumentError, "No URL options were specified" unless url_options
  raise ArgumentError, "No :host was specified; options are: #{url_options.inspect}" unless url_options[:host]
  validate_options url_options

  @url_options = url_options
  @scheme = normalize_scheme(url_options[:scheme] || url_options[:protocol])
  @root_uri = build_root_uri
end

Public Instance Methods

generate_url(path, base = "/") click to toggle source

Generate an absolute URL from a relative URL.

If the passed path is already an absolute URL or just an anchor reference, it will be returned as-is. If passed a blank path, the “root URL” will be returned. The root URL is the URL that the {#url_options} would generate by themselves.

An optional base can be specified. The base is another relative path from the root that specifies an “offset” from which the path was found in. A common use-case is to convert a relative path found in a stylesheet which resides in a subdirectory.

@example Normal conversions

generator = Roadie::UrlGenerator.new host: "foo.com", scheme: "https"
generator.generate_url("bar.html") # => "https://foo.com/bar.html"
generator.generate_url("/bar.html") # => "https://foo.com/bar.html"
generator.generate_url("") # => "https://foo.com"

@example Conversions with a base

generator = Roadie::UrlGenerator.new host: "foo.com", scheme: "https"
generator.generate_url("../images/logo.png", "/css") # => "https://foo.com/images/logo.png"
generator.generate_url("../images/logo.png", "/assets/css") # => "https://foo.com/assets/images/logo.png"

@param [String] base The base which the relative path comes from @return [String] an absolute URL

# File lib/roadie/url_generator.rb, line 58
def generate_url(path, base = "/")
  return root_uri.to_s if path.nil? or path.empty?
  return path if path_is_anchor?(path)
  return add_scheme(path) if path_is_schemeless?(path)
  return path if Utils.path_is_absolute?(path)

  combine_segments(root_uri, base, path).to_s
end

Private Instance Methods

add_scheme(path) click to toggle source
# File lib/roadie/url_generator.rb, line 77
def add_scheme(path)
  [scheme, path].join(":")
end
apply_base(base, path) click to toggle source
# File lib/roadie/url_generator.rb, line 89
def apply_base(base, path)
  if path[0] == "/"
    path
  else
    File.join(base, path)
  end
end
build_root_uri() click to toggle source
# File lib/roadie/url_generator.rb, line 71
def build_root_uri
  path = make_absolute url_options[:path]
  port = parse_port url_options[:port]
  URI::Generic.build(scheme: scheme, host: url_options[:host], port: port, path: path)
end
combine_segments(root, base, path) click to toggle source
# File lib/roadie/url_generator.rb, line 81
def combine_segments(root, base, path)
  new_path = apply_base(base, path)
  if root.path
    new_path = File.join(root.path, new_path)
  end
  root.merge(new_path)
end
make_absolute(path) click to toggle source
# File lib/roadie/url_generator.rb, line 107
def make_absolute(path)
  if path.nil? || path[0] == "/"
    path
  else
    "/#{path}"
  end
end
normalize_scheme(scheme) click to toggle source

Strip :// from any scheme, if present

# File lib/roadie/url_generator.rb, line 98
def normalize_scheme(scheme)
  return 'http' unless scheme
  scheme.to_s[/^\w+/]
end
parse_port(port) click to toggle source
# File lib/roadie/url_generator.rb, line 103
def parse_port(port)
  (port ? port.to_i : port)
end
path_is_anchor?(path) click to toggle source
# File lib/roadie/url_generator.rb, line 119
def path_is_anchor?(path)
  path.start_with? '#'
end
path_is_schemeless?(path) click to toggle source
# File lib/roadie/url_generator.rb, line 115
def path_is_schemeless?(path)
  path =~ %r{^//\w}
end
validate_options(options) click to toggle source
# File lib/roadie/url_generator.rb, line 125
def validate_options(options)
  keys = Set.new(options.keys)
  unless keys.subset? VALID_OPTIONS
    raise ArgumentError, "Passed invalid options: #{(keys - VALID_OPTIONS).to_a}, valid options are: #{VALID_OPTIONS.to_a}"
  end
end