Find out the parent context of a template rendered with .Render

I have an index.html with the following content. It ensures the latest post will be reproduced in full on the front page. So far so good

{{- $page := (index (where (site.RegularPages.Limit 1) "Type" "=" "blog") 0) }}

{{- with $page }}
{{- .Render "single" }}
{{- end }}

The problem is that instead of just showing the site title as the front page should, it shows the page title instead. It seems .IsHome always returns false in this context and there doesn’t seem to be any way to distinguish them from the sub rendered page ($.IsHome for instance is true inside the with but false inside the .Render call)

If I make a copy of single.html that doesn’t define main and define main in my index.html then the title is correct but I lose the convenient canonical link, description, etc.

I can get what I want by copy-pasting and tweaking several template files but I was wondering if there’s any easier way to get the information from the “outside” context so I don’t have to override half the theme.

First, I think you want this…

{{- $page := (index (where site.RegularPages "Type" "=" "blog") 0) }}

…instead of this:

{{- $page := (index (where (site.RegularPages.Limit 1) "Type" "=" "blog") 0) }}

Second, the result of this…

{{- .Render "single" }}

…depends on what “single” is (i.e., I don’t have enough information to answer your question).

First, I think you want this…

They do the same thing, I just thought the first might be more performant (Well it’s a small site so it probably doesn’t matter)

depends on what “single” is

It’s the PaperMod theme. The gist of layouts/_default/single.html is:

{{ define "main" }}

<h1>{{ .Title }}</h1>

{{ .Content }}

{{ end }}

So your standard single page template.

The problem is that if I .Render a single page template like this it’ll produce the <head> including all the page-specific stuff like the <title> which I want to change when it’s the front page of the site, but there’s no context to tell if I’m in the front page of the site any more.

I can get around it by duplicating a lot of template files and looking up the page twice – in the main block and in the head partial – but that seems hacky if there’s a better way to pass state into the .Render call

No, they do not. It will depend on how many content types you have and which is the latest. It could return no pages if you have a content type “foo” and one of the “foos” is the latest.

Oh I see, because .Limit is called first. I should have realized that

In your home page template, instead of using the Page.Render method, you could do this:

{{ $page := (index (where site.RegularPages "Type" "=" "blog") 0) }}
{{ $page.Content }}

Try it:

git clone --single-branch -b hugo-forum-topic-49476 https://github.com/jmooring/hugo-testing hugo-forum-topic-49476
cd hugo-forum-topic-49476
hugo server

Yeah but in practice that means duplicating a lot of templates like the head as well. I’ve already done that and it works I was just hoping there was a cleaner way to do it. I don’t suppose you could set data on the Page object itself from the template can you?

Page objects are immutable with the exception of setting Page.Scratch or Page.Store.

I guess I don’t understand your objective. I thought the goal was to reproduce the latest “blog” post on the home page. I’m missing some key aspect of what you are trying to do.

Perhaps you are trying to replace the home page with the latest “blog” post?

Perhaps you are trying to replace the home page with the latest “blog” post?

Yes, but I also wanted it to exist at its own url under /blog/, and I wanted the title on the home page to just be the site title. Unfortunately the page render itself is cached: Setting and unsetting a variable in Page.Scratch results in the same render on both the frontpage and the blog post:

{{- $page := (index (where site.RegularPages "Type" "=" "blog") 0) }}

{{ $page.Scratch.Set "isReallyHome" true }}

{{- with $page }}
{{- .Render "single" }}
{{- end }}

{{ $page.Scratch.Set "isReallyHome" false }}

So in the end I’ll just have to duplicate a bunch of templates. Oh well. Thanks anyway