diff --git a/lib/jekyll/filters/url_filters.rb b/lib/jekyll/filters/url_filters.rb index 777502d0718..72150a36d45 100644 --- a/lib/jekyll/filters/url_filters.rb +++ b/lib/jekyll/filters/url_filters.rb @@ -10,16 +10,20 @@ module URLFilters # Returns the absolute URL as a String. def absolute_url(input) return if input.nil? - - input = input.url if input.respond_to?(:url) - return input if Addressable::URI.parse(input.to_s).absolute? - - site = @context.registers[:site] - return relative_url(input) if site.config["url"].nil? - - Addressable::URI.parse( - site.config["url"].to_s + relative_url(input) - ).normalize.to_s + cache = (@context.registers[:cached_absolute_urls] ||= {}) + cache[input] ||= begin + input = input.url if input.respond_to?(:url) + site = @context.registers[:site] + if Addressable::URI.parse(input.to_s).absolute? + input + elsif site.config["url"].nil? + relative_url(input) + else + Addressable::URI.parse( + site.config["url"].to_s + relative_url(input) + ).normalize.to_s + end + end end # Produces a URL relative to the domain root based on site.baseurl @@ -30,14 +34,18 @@ def absolute_url(input) # Returns a URL relative to the domain root as a String. def relative_url(input) return if input.nil? - - input = input.url if input.respond_to?(:url) - return input if Addressable::URI.parse(input.to_s).absolute? - - parts = [sanitized_baseurl, input] - Addressable::URI.parse( - parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join - ).normalize.to_s + cache = (@context.registers[:cached_relative_urls] ||= {}) + cache[input] ||= begin + input = input.url if input.respond_to?(:url) + if Addressable::URI.parse(input.to_s).absolute? + input + else + parts = [sanitized_baseurl, input] + Addressable::URI.parse( + parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join + ).normalize.to_s + end + end end # Strips trailing `/index.html` from URLs to create pretty permalinks