gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
74.71k stars 7.45k forks source link

Add $page.RenderContent #10466

Open bep opened 1 year ago

bep commented 1 year ago

There is a similar issue in here somewhere, which stranded mostly because of ... naming. I'm deliberately not referring to that issue here, I suspect this needs a fresh approach.

type Page interface {
 RenderString(args ...any) (template.HTML, error)
 RenderContent(opts ...any) (Content, error)
}

I think I like the above:

The opts can probably be used for many things, but my first idea was to use it to solve a common problem with no current good solution in Hugo: {{ .Content }} will return the exactly the same whether rendered from a single or a list template. This is very performant, but thee are some situations where this is not ideal.

So, I thought we could start by introducing a variant option, e.g:

{{ $renderedContent := $somepage.RenderContent (dict "variant" "list") }}

Or something.

The $renderedContent above would be a struct with the common fields, and then probably some:

type Content struct {
  Content []byte
  WordCount int
 }

And and some table of contents things.

regisphilibert commented 1 year ago

So while .Content would return the string we're all familiar with, .RenderContent would return the struct described above which could be complemented with time without any breaking change. It's great!

What I don't understand though is how the variant will be relevant. How can I use this variant in my template, and won't the returned "RenderContent" always be the same regardless of the template "kind"?

regisphilibert commented 1 year ago

Of course after posting I thought about shortcodes and render hooks... Now any idea of how to access those parameters? Alongside the .Page in shortcodes and render-hooks is the first choice but I'm wondering if they shouldn't be stored in their own reserved key (like .Context or other) ...

Unreserved

Can be risky and not future proof

# render-link.html
{{ $class := cond  .variant "font-bold" "underline" }}
<a class="{{ $class }}" href="{{ .Destination | safeURL }}">{{ .Text | safeHTML }}</a>

Reserved

# render-link.html
{{ $class := cond .Context.variant "font-bold" "underline" }}
<a class="{{ $class }}" href="{{ .Destination | safeURL }}">{{ .Text | safeHTML }}</a>

I like the reserved key as it could be a constance known to all regardless of the "dot" structure of a template. If we ever allow parameters to be passed to the .Render templating method for example. One would also know to look for those in .Context rather than the root of the "dot" where all the page variables are also stored.

khayyamsaleem commented 1 year ago

I like the idea of the .Context reserved key to store additional parameters. Accordingly, I'd imagine we'd want the capability to list all entries in the context, or iterate over them.

I'd like to ramp up my contributions to hugo, so let me know (cc @bep) if this is a good issue for someone with moderate Go experience and an increasing understanding of the hugo codebase (or at least the templates / pages / shortcodes parts).