Inferring List/Section Type from First Item

After attempting to use .Type in a layouts/_default/list.html template I realized I was wrong to assume a list has the same .Type as stuff in it. I understand now this is because a list or section might not contain pages that all have the same type. Indeed, you could, and there are many cases where you would, want to change the type of a specific post.

But what if you are making a theme and want to imply the type for everything in the list? Here’s a snippet that grabs the type of the first item in the list and sets it to a variable you can use in the rest of the template:

<!-- infer the type for the list from the first item in it-->
{{ range first 1 .Data.Pages }}{{ $.Scratch.Add "type" .Type }} {{ end }}
{{ $type := $.Scratch.Get "type" }}

I combine this with partials in my _default/list.html to get around having to use Content Views, which require .Render and aren’t as good as partials in my opinion:

{{ partial "top" . }}
{{ range where .Data.Pages "File.LogicalName" "" }}
  {{ partial (print "types/" $type "/intro") . }}
{{ end }}
{{ range where .Data.Pages "File.LogicalName" "not in" (split "," ",") }}
  {{ partial (print "types/" $type "/summary") . }}
{{ end }}
{{ range where .Data.Pages "File.LogicalName" "" }}
  {{ partial (print "types/" $type "/outro") . }}
{{ end }}
{{ partial "bottom" . }}

As always, I’d love to hear any other better ways of doing this. Thanks.

I think this is better:

{{ range $i, $e := where .Data.Pages "File.LogicalName" "" }}
  {{ if $i eq 0 }}
  {{ $type := $e.Type }}
 {{ end }}
  {{ partial (print "types/" $type "/outro") $e }}
{{ end }}

Or something like that.Totally untested, but I don’t think you need scratch and picking the first for every list will be more accurate.

Well I used .Scratch because the $type decl/def is within the more limited scope and can’t be seen by the partial call later. Has to be a better way without nesting the whole thing, but .Scratch, as much of a hack as it seems, worked.