Class: Bunto::URL
- Inherits:
-
Object
- Object
- Bunto::URL
- Defined in:
- lib/bunto/url.rb
Class Method Summary collapse
-
.escape_path(path) ⇒ Object
Escapes a path to be a valid URL path segment.
-
.unescape_path(path) ⇒ Object
Unescapes a URL path segment.
Instance Method Summary collapse
-
#generate_url(template) ⇒ Object
Internal: Generate the URL by replacing all placeholders with their respective values in the given template.
- #generate_url_from_drop(template) ⇒ Object
- #generate_url_from_hash(template) ⇒ Object
-
#generated_permalink ⇒ Object
Generates a URL from the permalink.
-
#generated_url ⇒ Object
Generates a URL from the template.
-
#initialize(options) ⇒ URL
constructor
options - One of :permalink or :template must be supplied.
-
#sanitize_url(str) ⇒ Object
Returns a sanitized String URL, stripping “../../” and multiples of “/”, as well as the beginning “/” so we can enforce and ensure it.
-
#to_s ⇒ Object
The generated relative URL of the resource.
Constructor Details
#initialize(options) ⇒ URL
options - One of :permalink or :template must be supplied.
:template - The String used as template for URL generation,
for example "/:path/:basename:output_ext", where
a placeholder is prefixed with a colon.
:placeholders - A hash containing the placeholders which will be
replaced when used inside the template. E.g.
{ "year" => Time.now.strftime("%Y") } would replace
the placeholder ":year" with the current year.
:permalink - If supplied, no URL will be generated from the
template. Instead, the given permalink will be
used as URL.
25 26 27 28 29 30 31 32 33 |
# File 'lib/bunto/url.rb', line 25 def initialize() @template = [:template] @placeholders = [:placeholders] || {} @permalink = [:permalink] if (@template || @permalink).nil? raise ArgumentError, "One of :template or :permalink must be supplied." end end |
Class Method Details
.escape_path(path) ⇒ Object
Escapes a path to be a valid URL path segment
path - The path to be escaped.
Examples:
URL.escape_path("/a b")
# => "/a%20b"
Returns the escaped path.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/bunto/url.rb', line 115 def self.escape_path(path) # Because URI.escape doesn't escape "?", "[" and "]" by default, # specify unsafe string (except unreserved, sub-delims, ":", "@" and "/"). # # URI path segment is defined in RFC 3986 as follows: # segment = *pchar # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" # pct-encoded = "%" HEXDIG HEXDIG # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" # / "*" / "+" / "," / ";" / "=" URI.escape(path, %r{[^a-zA-Z\d\-._~!$&'()*+,;=:@\/]}).encode("utf-8") end |
.unescape_path(path) ⇒ Object
Unescapes a URL path segment
path - The path to be unescaped.
Examples:
URL.unescape_path("/a%20b")
# => "/a b"
Returns the unescaped path.
139 140 141 |
# File 'lib/bunto/url.rb', line 139 def self.unescape_path(path) URI.unescape(path.encode("utf-8")) end |
Instance Method Details
#generate_url(template) ⇒ Object
Internal: Generate the URL by replacing all placeholders with their respective values in the given template
Returns the unsanitized String URL
67 68 69 70 71 72 73 |
# File 'lib/bunto/url.rb', line 67 def generate_url(template) if @placeholders.is_a? Drops::UrlDrop generate_url_from_drop(template) else generate_url_from_hash(template) end end |
#generate_url_from_drop(template) ⇒ Object
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/bunto/url.rb', line 87 def generate_url_from_drop(template) template.gsub(%r!:([a-z_]+)!) do |match| replacement = @placeholders.public_send(match.sub(":".freeze, "".freeze)) if replacement.nil? "".freeze else self.class.escape_path(replacement) end end.gsub(%r!//!, "/".freeze) end |
#generate_url_from_hash(template) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/bunto/url.rb', line 75 def generate_url_from_hash(template) @placeholders.inject(template) do |result, token| break result if result.index(":").nil? if token.last.nil? # Remove leading "/" to avoid generating urls with `//` result.gsub(%r!/:#{token.first}!, "") else result.gsub(%r!:#{token.first}!, self.class.escape_path(token.last)) end end end |
#generated_permalink ⇒ Object
Generates a URL from the permalink
Returns the _unsanitized String URL
52 53 54 |
# File 'lib/bunto/url.rb', line 52 def generated_permalink (@generated_permalink ||= generate_url(@permalink)) if @permalink end |
#generated_url ⇒ Object
Generates a URL from the template
Returns the unsanitized String URL
59 60 61 |
# File 'lib/bunto/url.rb', line 59 def generated_url @generated_url ||= generate_url(@template) end |
#sanitize_url(str) ⇒ Object
Returns a sanitized String URL, stripping “../../” and multiples of “/”, as well as the beginning “/” so we can enforce and ensure it.
101 102 103 |
# File 'lib/bunto/url.rb', line 101 def sanitize_url(str) "/" + str.gsub(%r!/{2,}!, "/").gsub(%r!\.+/|\A/+!, "") end |
#to_s ⇒ Object
The generated relative URL of the resource
Returns the String URL Raises a Bunto::Errors::InvalidURLError if the relative URL contains a colon
39 40 41 42 43 44 45 46 47 |
# File 'lib/bunto/url.rb', line 39 def to_s sanitized_url = sanitize_url(generated_permalink || generated_url) if sanitized_url.include?(":") raise Bunto::Errors::InvalidURLError, "The URL #{sanitized_url} is invalid because it contains a colon." else sanitized_url end end |