Pass .RenderShortcodes' Page to render hooks as .PageInner

The main use case for this is to resolve links and resources (e.g. images) relative to the included `Page`.

A typical `include` would similar to this:

```handlebars
{{ with site.GetPage (.Get 0) }}
  {{ .RenderShortcodes }}
{{ end }}
```

And when used in a Markdown file:

```markdown
{{% include "/posts/p1" %}}
```

Any render hook triggered while rendering `/posts/p1` will get `/posts/p1` when calling `.PageInner`.

Note that

* This is only relevant for shortcodes included with `{{%` that calls `.RenderShortcodes`.
* `.PageInner` is available in all render hooks that, before this commit, received `.Page`.
* `.PageInner` will fall back to the value of `.Page` if not relevant and will always have a value.

Fixes #12356
This commit is contained in:
Bjørn Erik Pedersen
2024-04-11 17:46:18 +02:00
parent a18e2bcb9a
commit df11327ba9
18 changed files with 443 additions and 28 deletions

View File

@@ -30,6 +30,7 @@ import (
"github.com/spf13/cast"
"github.com/gohugoio/hugo/markup/converter/hooks"
"github.com/gohugoio/hugo/markup/goldmark/hugocontext"
"github.com/gohugoio/hugo/markup/highlight/chromalexers"
"github.com/gohugoio/hugo/markup/tableofcontents"
@@ -68,8 +69,9 @@ var (
func newPageContentOutput(po *pageOutput) (*pageContentOutput, error) {
cp := &pageContentOutput{
po: po,
renderHooks: &renderHooks{},
po: po,
renderHooks: &renderHooks{},
otherOutputs: make(map[uint64]*pageContentOutput),
}
return cp, nil
}
@@ -83,6 +85,10 @@ type renderHooks struct {
type pageContentOutput struct {
po *pageOutput
// Other pages involved in rendering of this page,
// typically included with .RenderShortcodes.
otherOutputs map[uint64]*pageContentOutput
contentRenderedVersion int // Incremented on reset.
contentRendered bool // Set on content render.
@@ -165,6 +171,13 @@ func (pco *pageContentOutput) RenderShortcodes(ctx context.Context) (template.HT
cb(pco, ct)
}
if tpl.Context.IsInGoldmark.Get(ctx) {
// This content will be parsed and rendered by Goldmark.
// Wrap it in a special Hugo markup to assign the correct Page from
// the stack.
c = hugocontext.Wrap(c, pco.po.p.pid)
}
return helpers.BytesToHTML(c), nil
}