From 9c0c518d524463c9915cd35aa172134a4f7875cf Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Mon, 13 Apr 2020 13:22:54 +0530 Subject: [PATCH] Cache URLFilter results of string inputs per site (#7990) Merge pull request 7990 --- lib/jekyll/filters/url_filters.rb | 28 ++++++++++++++++++++++------ lib/jekyll/site.rb | 3 ++- test/test_filters.rb | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/jekyll/filters/url_filters.rb b/lib/jekyll/filters/url_filters.rb index 5d984096160..a7dd4dbb37b 100644 --- a/lib/jekyll/filters/url_filters.rb +++ b/lib/jekyll/filters/url_filters.rb @@ -9,8 +9,18 @@ module URLFilters # # Returns the absolute URL as a String. def absolute_url(input) - cache = (@context.registers[:cached_absolute_urls] ||= {}) + return if input.nil? + + cache = if input.is_a?(String) + (@context.registers[:site].filter_cache[:absolute_url] ||= {}) + else + (@context.registers[:cached_absolute_url] ||= {}) + end cache[input] ||= compute_absolute_url(input) + + # Duplicate cached string so that the cached value is never mutated by + # a subsequent filter. + cache[input].dup end # Produces a URL relative to the domain root based on site.baseurl @@ -20,8 +30,18 @@ def absolute_url(input) # # Returns a URL relative to the domain root as a String. def relative_url(input) - cache = (@context.registers[:cached_relative_urls] ||= {}) + return if input.nil? + + cache = if input.is_a?(String) + (@context.registers[:site].filter_cache[:relative_url] ||= {}) + else + (@context.registers[:cached_relative_url] ||= {}) + end cache[input] ||= compute_relative_url(input) + + # Duplicate cached string so that the cached value is never mutated by + # a subsequent filter. + cache[input].dup end # Strips trailing `/index.html` from URLs to create pretty permalinks @@ -38,8 +58,6 @@ 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? @@ -53,8 +71,6 @@ def compute_absolute_url(input) 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? diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index b8d021013aa..5195a377e1e 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -10,7 +10,7 @@ class Site :gems, :plugin_manager, :theme attr_accessor :converters, :generators, :reader - attr_reader :regenerator, :liquid_renderer, :includes_load_paths + attr_reader :regenerator, :liquid_renderer, :includes_load_paths, :filter_cache # Public: Initialize a new Site. # @@ -23,6 +23,7 @@ def initialize(config) self.config = config @cache_dir = in_source_dir(config["cache_dir"]) + @filter_cache = {} @reader = Reader.new(self) @regenerator = Regenerator.new(self) diff --git a/test/test_filters.rb b/test/test_filters.rb index 89a586cca4e..6450cae822f 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -596,6 +596,7 @@ def select; end assert_equal "/front_matter.erb", page.url url = filter.relative_url(page.url) url << "foo" + assert_equal "/front_matter.erb", filter.relative_url(page.url) assert_equal "/front_matter.erb", page.url end