Repository: gohugoio/hugo (language: go)

Issue:
ContentWithoutSummary should return .Content when summary is fetched from front matter
>The ContentWithoutSummary method returns an empty string if you define the content summary in front matter.

Reading @jmooring 's documentation on this, I was a little surprised about my own implementation. I guess I was a little too occupied about the summary types that actually splits the content.

I would say that `ContentWithoutSummary` should return `Content`  when summary is fetched from front matter.

Shout if you disagree. 
Some Obsidian styled alerts result in invalid HTML
Given the following Markdown:

````md
> [!caution] Callouts can have custom titles
> Like this one.

> [!caution] Title-only callout

> [!note]- Are callouts foldable?
> Yes! In a foldable callout, the contents are hidden when the callout is collapsed

> [!note]+ Are callouts foldable?
> Yes! In a foldable callout, the contents are hidden when the callout is collapsed

> [!info] Can callouts be nested?
> > [!important] Yes!, they can.
> > > [!tip]  You can even use multiple layers of nesting.
````

and the following `render-blockquote.html`

````
{{ warnf "%s" .AlertTitle }}
````

somtimes results in a closing `</p>` at the end of the title

````
WARN  Callouts can have custom titles
WARN  Title-only callout</p>
WARN  Are callouts foldable?
WARN  You can even use multiple layers of nesting.</p>
WARN  Yes!, they can.</p>
WARN  Can callouts be nested?</p>
````

### What version of Hugo are you using (`hugo version`)?

<pre>
$ hugo version
hugo v0.134.0-77df7bbbff8ce6b56ed693270088de973a87d5ce+extended windows/amd64 BuildDate=2024-09-03T09:54:22Z VendorInfo=gohugoio
</pre>

### Does this issue reproduce with the latest release?
Yes



Discussion / hints:

Fix patch:
diff --git a/hugolib/page__content.go b/hugolib/page__content.go
index cc93fe5d5cf..4ec91f7b5cd 100644
--- a/hugolib/page__content.go
+++ b/hugolib/page__content.go
@@ -504,7 +504,7 @@ type contentTableOfContents struct {
 }
 
 type contentSummary struct {
-	content               string
+	content               template.HTML
 	contentWithoutSummary template.HTML
 	summary               page.Summary
 }
@@ -612,9 +612,9 @@ func (c *cachedContentScope) contentRendered(ctx context.Context) (contentSummar
 					Truncated: summarized.Truncated(),
 				}
 				result.contentWithoutSummary = template.HTML(summarized.ContentWithoutSummary())
-				result.content = summarized.Content()
+				result.content = template.HTML(summarized.Content())
 			} else {
-				result.content = string(b)
+				result.content = template.HTML(string(b))
 			}
 
 			if !c.pi.hasSummaryDivider && cp.po.p.m.pageConfig.Summary == "" {
@@ -646,6 +646,7 @@ func (c *cachedContentScope) contentRendered(ctx context.Context) (contentSummar
 				Text: helpers.BytesToHTML(html),
 				Type: page.SummaryTypeFrontMatter,
 			}
+			rs.Value.contentWithoutSummary = rs.Value.content
 		}
 
 		return rs, err
@@ -879,7 +880,7 @@ func (c *cachedContentScope) Content(ctx context.Context) (template.HTML, error)
 	if err != nil {
 		return "", err
 	}
-	return template.HTML(cr.content), nil
+	return cr.content, nil
 }
 
 func (c *cachedContentScope) ContentWithoutSummary(ctx context.Context) (template.HTML, error) {
diff --git a/markup/goldmark/blockquotes/blockquotes.go b/markup/goldmark/blockquotes/blockquotes.go
index f6d1a590ee0..f9d518850af 100644
--- a/markup/goldmark/blockquotes/blockquotes.go
+++ b/markup/goldmark/blockquotes/blockquotes.go
@@ -164,10 +164,12 @@ var blockQuoteAlertRe = regexp.MustCompile(`^<p>\[!([a-zA-Z]+)\](-|\+)?[^\S\r\n]
 func resolveBlockQuoteAlert(s string) blockQuoteAlert {
 	m := blockQuoteAlertRe.FindStringSubmatch(s)
 	if len(m) == 4 {
+		title := strings.TrimSpace(m[3])
+		title = strings.TrimRight(title, "</p>")
 		return blockQuoteAlert{
 			typ:   strings.ToLower(m[1]),
 			sign:  m[2],
-			title: m[3],
+			title: title,
 		}
 	}
 


Test patch:
diff --git a/hugolib/page_test.go b/hugolib/page_test.go
index 47f7c59c9fd..66afd7d966e 100644
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -523,7 +523,7 @@ categories: ["cool stuff"]
 	for _, p := range s.Pages() {
 		checkDated(p, p.Kind())
 	}
-	checkDate(s.LastChange(), "site")
+	checkDate(s.Lastmod(), "site")
 }
 
 func TestPageDatesSections(t *testing.T) {
diff --git a/hugolib/securitypolicies_test.go b/hugolib/securitypolicies_test.go
index b0d39c69775..3ddda7d6a06 100644
--- a/hugolib/securitypolicies_test.go
+++ b/hugolib/securitypolicies_test.go
@@ -185,35 +185,6 @@ urls="none"
 [security.http]
 mediaTypes=["application/json"]
 
-`)
-			})
-	})
-
-	c.Run("getJSON, OK", func(c *qt.C) {
-		c.Parallel()
-		httpTestVariant(c, `{{ $json := getJSON "%[1]s/fruits.json" }}{{ $json.Content }}`, "", nil)
-	})
-
-	c.Run("getJSON, denied URL", func(c *qt.C) {
-		c.Parallel()
-		httpTestVariant(c, `{{ $json := getJSON "%[1]s/fruits.json" }}{{ $json.Content }}`, `(?s).*is not whitelisted in policy "security\.http\.urls".*`,
-			func(b *sitesBuilder) {
-				b.WithConfigFile("toml", `
-[security]		
-[security.http]
-urls="none"		
-`)
-			})
-	})
-
-	c.Run("getCSV, denied URL", func(c *qt.C) {
-		c.Parallel()
-		httpTestVariant(c, `{{ $d := getCSV ";" "%[1]s/cities.csv" }}{{ $d.Content }}`, `(?s).*is not whitelisted in policy "security\.http\.urls".*`,
-			func(b *sitesBuilder) {
-				b.WithConfigFile("toml", `
-[security]		
-[security.http]
-urls="none"		
 `)
 			})
 	})
diff --git a/hugolib/site_stats_test.go b/hugolib/site_stats_test.go
index 167194ef580..7fd68ff44bb 100644
--- a/hugolib/site_stats_test.go
+++ b/hugolib/site_stats_test.go
@@ -121,11 +121,10 @@ date: 2023-04-01
 ---
 -- layouts/index.html --
 site.Lastmod: {{ .Site.Lastmod.Format "2006-01-02" }}
-site.LastChange: {{ .Site.LastChange.Format "2006-01-02" }}
 home.Lastmod: {{ site.Home.Lastmod.Format "2006-01-02" }}
 
 `
 	b := Test(t, files)
 
-	b.AssertFileContent("public/index.html", "site.Lastmod: 2023-04-01\nsite.LastChange: 2023-04-01\nhome.Lastmod: 2023-01-01")
+	b.AssertFileContent("public/index.html", "site.Lastmod: 2023-04-01\nhome.Lastmod: 2023-01-01")
 }
diff --git a/hugolib/site_test.go b/hugolib/site_test.go
index 37546824a11..2ee33da246a 100644
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -147,8 +147,8 @@ func TestLastChange(t *testing.T) {
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Configs: configs}, BuildCfg{SkipRender: true})
 
-	c.Assert(s.LastChange().IsZero(), qt.Equals, false)
-	c.Assert(s.LastChange().Year(), qt.Equals, 2017)
+	c.Assert(s.Lastmod().IsZero(), qt.Equals, false)
+	c.Assert(s.Lastmod().Year(), qt.Equals, 2017)
 }
 
 // Issue #_index
diff --git a/markup/goldmark/blockquotes/blockquotes_integration_test.go b/markup/goldmark/blockquotes/blockquotes_integration_test.go
index af3c1fba49a..1f671df2b20 100644
--- a/markup/goldmark/blockquotes/blockquotes_integration_test.go
+++ b/markup/goldmark/blockquotes/blockquotes_integration_test.go
@@ -123,7 +123,6 @@ title: "Home"
 > [!danger]
 > Do not approach or handle without protective gear.
 
-
 > [!tip] Callouts can have custom titles
 > Like this one.
 
@@ -135,6 +134,10 @@ title: "Home"
 > [!faq]+ Foldable callout
 > Yes! In a foldable callout, the contents are hidden when the callout is collapsed
 
+> [!info] Can callouts be nested?
+> > [!important] Yes!, they can.
+> > > [!tip] You can even use multiple layers of nesting.
+
 -- layouts/index.html --
 {{ .Content }}
 -- layouts/_default/_markup/render-blockquote.html --
@@ -145,9 +148,11 @@ AlertType: {{ .AlertType }}|AlertTitle: {{ .AlertTitle }}|AlertSign: {{ .AlertSi
 	b := hugolib.Test(t, files)
 	b.AssertFileContentExact("public/index.html",
 		"AlertType: tip|AlertTitle: Callouts can have custom titles|AlertSign: |",
-		"AlertType: tip|AlertTitle: Title-only callout</p>|AlertSign: |",
-		"AlertType: faq|AlertTitle: Foldable negated callout|AlertSign: -|Text: <p>Yes!",
-		"AlertType: faq|AlertTitle: Foldable callout|AlertSign: +|",
+		"AlertType: tip|AlertTitle: Title-only callout|AlertSign: |",
+		"AlertType: faq|AlertTitle: Foldable negated callout|AlertSign: -|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>\n|",
+		"AlertType: faq|AlertTitle: Foldable callout|AlertSign: +|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>\n|",
 		"AlertType: danger|AlertTitle: |AlertSign: |Text: <p>Do not approach or handle without protective gear.</p>\n|",
+		"AlertTitle: Can callouts be nested?|",
+		"AlertTitle: You can even use multiple layers of nesting.|",
 	)
 }
diff --git a/markup/goldmark/blockquotes/blockquotes_test.go b/markup/goldmark/blockquotes/blockquotes_test.go
index 8b948af08c1..067cf366e75 100644
--- a/markup/goldmark/blockquotes/blockquotes_test.go
+++ b/markup/goldmark/blockquotes/blockquotes_test.go
@@ -63,6 +63,6 @@ func TestResolveBlockQuoteAlert(t *testing.T) {
 	}
 
 	for i, test := range tests {
-		c.Assert(resolveBlockQuoteAlert("<p>"+test.input), qt.Equals, test.expected, qt.Commentf("Test %d", i))
+		c.Assert(resolveBlockQuoteAlert("<p>"+test.input+"</p>"), qt.Equals, test.expected, qt.Commentf("Test %d", i))
 	}
 }
diff --git a/resources/page/page_markup_integration_test.go b/resources/page/page_markup_integration_test.go
index fc3c6a5691e..010a9d729a5 100644
--- a/resources/page/page_markup_integration_test.go
+++ b/resources/page/page_markup_integration_test.go
@@ -171,7 +171,7 @@ includecontent: {{ hugo.Context.MarkupScope }}|{{ $p.Markup.Render.Content }}|
 	)
 }
 
-func TestPageMarkupWithoutSummary(t *testing.T) {
+func TestPageContentWithoutSummary(t *testing.T) {
 	t.Parallel()
 
 	files := `
@@ -195,6 +195,13 @@ This is some content about a summary and more.
 Another paragraph.
 
 Third paragraph.
+-- content/p3.md --
+---
+title: "Post 3"
+date: "2020-01-01"
+summary: "This is summary in front matter."
+---
+This is content.
 -- layouts/_default/single.html --
 Single.
 Page.Summary: {{ .Summary }}|
@@ -229,6 +236,11 @@ Summary Truncated: {{ .Truncated }}|
 		"Summary Type: auto",
 		"Summary Truncated: true",
 	)
+
+	b.AssertFileContentExact("public/p3/index.html",
+		"Summary: This is summary in front matter.|",
+		"ContentWithoutSummary: <p>This is content.</p>\n|",
+	)
 }
 
 func TestPageMarkupWithoutSummaryRST(t *testing.T) {