diff --git a/lib/jekyll/page.rb b/lib/jekyll/page.rb index b1b713a661d..20eefe96726 100644 --- a/lib/jekyll/page.rb +++ b/lib/jekyll/page.rb @@ -49,6 +49,7 @@ def initialize(site, base, dir, name) process(name) read_yaml(PathManager.join(base, dir), name) + generate_excerpt if site.config["page_excerpts"] data.default_proc = proc do |_, key| site.frontmatter_defaults.find(relative_path, type, key) @@ -185,14 +186,25 @@ def write? end def excerpt_separator - @excerpt_separator ||= data["excerpt_separator"] || site.config["excerpt_separator"] || "" + @excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s end def excerpt - return if excerpt_separator.empty? || !site.config["page_excerpts"] - return data["excerpt"] unless self.class == Jekyll::Page && html? + return @excerpt if defined?(@excerpt) - data["excerpt"] ||= Jekyll::PageExcerpt.new(self).to_liquid + @excerpt = data["excerpt"]&.to_s + end + + def generate_excerpt? + !excerpt_separator.empty? && self.class == Jekyll::Page && html? + end + + private + + def generate_excerpt + return unless generate_excerpt? + + data["excerpt"] ||= Jekyll::PageExcerpt.new(self) end end end diff --git a/lib/jekyll/page_excerpt.rb b/lib/jekyll/page_excerpt.rb index c1bae50ffcf..dd79fca8d78 100644 --- a/lib/jekyll/page_excerpt.rb +++ b/lib/jekyll/page_excerpt.rb @@ -2,15 +2,14 @@ module Jekyll class PageExcerpt < Excerpt - attr_reader :output, :doc + attr_reader :doc alias_method :id, :relative_path - # The Liquid representation of this instance is simply the rendered output string. - alias_method :to_liquid, :output + EXCERPT_ATTRIBUTES = (Page::ATTRIBUTES_FOR_LIQUID - %w(excerpt)).freeze + private_constant :EXCERPT_ATTRIBUTES - def initialize(doc) - super - self.output = Renderer.new(site, self, site.site_payload).run + def to_liquid + @to_liquid ||= doc.to_liquid(EXCERPT_ATTRIBUTES) end def render_with_liquid? diff --git a/test/source/assets/test-styles.scss b/test/source/assets/test-styles.scss index 5c9e870dc74..bf14345a0c6 100644 --- a/test/source/assets/test-styles.scss +++ b/test/source/assets/test-styles.scss @@ -1,4 +1,4 @@ ---- ---- - -@import "{{ site.skin | default: 'grid' }}"; +--- +--- + +@import "{{ site.skin | default: 'grid' }}"; diff --git a/test/source/contacts/foo.md b/test/source/contacts/foo.md new file mode 100644 index 00000000000..4e41bebc11a --- /dev/null +++ b/test/source/contacts/foo.md @@ -0,0 +1,7 @@ +--- +title: Contact Information +--- + +## {{ page.title }} + +In case of emergency, contact Mr. John Doe, 1234, Foo Road, Foo. diff --git a/test/test_filters.rb b/test/test_filters.rb index 1136625a09d..b819b9122f6 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -816,7 +816,7 @@ def to_liquid "The list of grouped items for '' is not an Array." ) # adjust array.size to ignore symlinked page in Windows - qty = Utils::Platforms.really_windows? ? 18 : 20 + qty = Utils::Platforms.really_windows? ? 19 : 21 assert_equal qty, g["items"].size end end @@ -1310,7 +1310,7 @@ def to_liquid "The list of grouped items for '' is not an Array." ) # adjust array.size to ignore symlinked page in Windows - qty = Utils::Platforms.really_windows? ? 18 : 20 + qty = Utils::Platforms.really_windows? ? 19 : 21 assert_equal qty, g["items"].size end end diff --git a/test/test_page.rb b/test/test_page.rb index ba513b2f251..d6c485a96f9 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -369,22 +369,39 @@ def do_render(page) end context "read-in by default" do - should "not expose an excerpt to Liquid templates" do + should "not initialize excerpts by default" do + page = setup_page("contacts", "foo.md") + assert_nil page.excerpt + end + + should "not expose an excerpt to Liquid templates by default" do page = setup_page("/contacts", "bar.html") assert_nil page.to_liquid["excerpt"] end - should "expose an excerpt to Liquid templates if site is configured to" do - configured_site = fixture_site("page_excerpts" => true) - test_page = Jekyll::Page.new(configured_site, source_dir, "/contacts", "bar.html") - assert_equal "Contact Information\n", test_page.to_liquid["excerpt"] - end + context "in a site configured to generate page excerpts" do + setup { @configured_site = fixture_site("page_excerpts" => true) } + + should "initialize excerpt eagerly but render only when needed" do + test_page = Jekyll::Page.new(@configured_site, source_dir, "contacts", "foo.md") + assert_equal Jekyll::PageExcerpt, test_page.data["excerpt"].class + assert_equal String, test_page.excerpt.class + assert_equal( + "

Contact Information

\n", + test_page.excerpt + ) + end + + should "expose an excerpt to Liquid templates" do + test_page = Jekyll::Page.new(@configured_site, source_dir, "/contacts", "bar.html") + assert_equal "Contact Information\n", test_page.to_liquid["excerpt"] + end - should "not expose an excerpt for non-html pages even in a configured site" do - configured_site = fixture_site("page_excerpts" => true) - test_page = Jekyll::Page.new(configured_site, source_dir, "assets", "test-styles.scss") - refute_equal ".half { width: 50%; }\n", test_page.to_liquid["excerpt"] - assert_nil test_page.to_liquid["excerpt"] + should "not expose an excerpt for non-html pages" do + test_page = Jekyll::Page.new(@configured_site, source_dir, "assets", "test-styles.scss") + refute_equal ".half { width: 50%; }\n", test_page.to_liquid["excerpt"] + assert_nil test_page.to_liquid["excerpt"] + end end end diff --git a/test/test_site.rb b/test/test_site.rb index e0c7822f39c..eabfe346606 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -232,6 +232,7 @@ def generate(site) environment.html exploit.md foo.md + foo.md humans.txt index.html index.html