From 55fba8ff313aae36b3d3e9d05cad7223a9af734b Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Thu, 22 Aug 2019 09:51:33 -0400 Subject: [PATCH] Memoize absolute_url and relative_url filters (#7793) Merge pull request 7793 --- lib/jekyll/filters/url_filters.rb | 50 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/lib/jekyll/filters/url_filters.rb b/lib/jekyll/filters/url_filters.rb index 777502d0718..2c8e268884b 100644 --- a/lib/jekyll/filters/url_filters.rb +++ b/lib/jekyll/filters/url_filters.rb @@ -9,17 +9,8 @@ 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] ||= compute_absolute_url(input) end # Produces a URL relative to the domain root based on site.baseurl @@ -29,15 +20,8 @@ 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] ||= compute_relative_url(input) end # Strips trailing `/index.html` from URLs to create pretty permalinks @@ -53,6 +37,32 @@ def strip_index(input) private + def compute_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 + end + + def compute_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 + end + def sanitized_baseurl site = @context.registers[:site] site.config["baseurl"].to_s.chomp("/")