From 459cdeb5415ce66861120befe2b121380e043a03 Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Wed, 19 Jan 2022 22:14:01 -0500 Subject: [PATCH] Evaluate post-summary divider HTML shortcodes In HTML content pages with summary dividers, shortcodes after the summary divider are not evaluated but are simply printed as-is within the .Content of the page. The issue takes place in hugolib.newPageContentOutput. In this function, we apply various transformations to cp.workContent, and at the end of the function, make this assignment: cp.content = helpers.BytesToHTML(cp.workContent) If a page has a manual summary divider and is HTML, we perform this transformation on cp.workContent: cp.workContent = src[cp.p.source.posBodyStart:] While this sets the workContent to all content after the summary divider, it does so *after* newPageContentOutput calls replaceShortcodeTokens and evaluates shortcodes. This means that evaluated shortcodes are replaced with unevaluated ones after the summary divider. The fix is to reuse logic from the function we use to evaluate the summary divider for non-HTML pages, hugolib.splitUserDefinedSummaryAndContent. While the current code branches on whether the page is HTML before calling this function, this change branches within the function, since the function already includes a "markup" parameter we can use to perform the branching. And since this function already splits the summary/content while preserving evaluated shortcodes, we can reuse its splitting logic to fix the issue. Fixes #6513 --- hugolib/page__per_output.go | 38 ++++++++++---------- hugolib/page_test.go | 72 +++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 20 deletions(-) diff --git a/hugolib/page__per_output.go b/hugolib/page__per_output.go index bd4e35a5b0c..86f9039c684 100644 --- a/hugolib/page__per_output.go +++ b/hugolib/page__per_output.go @@ -164,26 +164,12 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err } if cp.p.source.hasSummaryDivider { - if isHTML { - src := p.source.parsed.Input() - - // Use the summary sections as they are provided by the user. - if p.source.posSummaryEnd != -1 { - cp.summary = helpers.BytesToHTML(src[p.source.posMainContent:p.source.posSummaryEnd]) - } - - if cp.p.source.posBodyStart != -1 { - cp.workContent = src[cp.p.source.posBodyStart:] - } - + summary, content, err := splitUserDefinedSummaryAndContent(cp.p.m.markup, cp.workContent) + if err != nil { + cp.p.s.Log.Errorf("Failed to set user defined summary for page %q: %s", cp.p.pathOrTitle(), err) } else { - summary, content, err := splitUserDefinedSummaryAndContent(cp.p.m.markup, cp.workContent) - if err != nil { - cp.p.s.Log.Errorf("Failed to set user defined summary for page %q: %s", cp.p.pathOrTitle(), err) - } else { - cp.workContent = content - cp.summary = helpers.BytesToHTML(summary) - } + cp.workContent = content + cp.summary = helpers.BytesToHTML(summary) } } else if cp.p.m.summary != "" { b, err := cp.renderContent([]byte(cp.p.m.summary), false) @@ -628,6 +614,12 @@ func splitUserDefinedSummaryAndContent(markup string, c []byte) (summary []byte, start := bytes.LastIndex(c[:startDivider], []byte("<"+startTag)) end := bytes.Index(c[startDivider:], []byte(" +{{< ten >}} +`, + `posts/htmlwithnomore.html`, + ` +--- +title: HTML with a frontmatter summary +summary: summary +--- +{{< ten >}} +`, + `posts/mdwithmore.md`, + ` +--- +title: MD with a manual summary +--- +summary + +{{< ten >}} +`, + `posts/mdwithnomore.md`, + ` +--- +title: MD with a frontmatter summary +summary: summary +--- +{{< ten >}} +`, + ) + + err := b.BuildE(BuildCfg{}) + + c.Assert(err, qt.Equals, nil) + // Not including the summary in the content for HTML pages + b.AssertFileContent( + "public/posts/htmlwithmore/index.html", + `10`, + ) + b.AssertFileContent( + "public/posts/htmlwithnomore/index.html", + `10`, + ) + b.AssertFileContent( + "public/posts/mdwithmore/index.html", + `

summary

+10`, + ) + b.AssertFileContent( + "public/posts/mdwithnomore/index.html", + `10`, + ) +}