Using $.Scratch to redefine classes in partial depending on context/layout

Perhaps this isn’t the best use of scratch. I have created a hero partial that I want to use across a few different areas of the site, but the classes and content therein will change according to context. There are three hero types:

  • Homepage: index.html
  • List/section/node: layouts/section/thesectionname.html
  • Individual page: layouts/thesectionname/single.html

Here is where it gets tricky. The “hero” of the homepage (layouts/index.html) is the most recently published blog post, which I am presenting as the “featured article.” Each section homepage (ie, layouts/section/thesectionname.html) has a “section hero” that has less markup than the homepage hero. Each single blog post (layouts/blog/single.html) also contains a hero with the title, publish date, etc of that individual post but does not include all the “featured article” pieces as that of the homepage hero.

  1. Here is my partials/components/hero.html:

    {{$pagetype := $.Scratch.Get "pagetype"}}
    
  2. Homepage hero. This is actually the most recently published blog post. This works A-okay in terms of surfacing what I need to the site homepage.

    <!--top of my layouts/index.html; note how I am trying to redefine "pagetype"-->
    {{$.Scratch.Set "pagetype" "homepage"}}
    {{ range first 1 ((where .Site.Pages "Section" "blog").ByPublishDate.Reverse) }}
        {{partial "components/hero.html" . }}
    {{end}}
    
  3. Post hero. This is at the top of layouts/blog/single.html

    {{$.Scratch.Set "pagetype" "single-post"}}
    <main id="main-content">
    {{partial "components/hero.html" . }}
    

However, regardless of where I put {{$pagetype}}, I am getting the string “single-post,” when what I want to get is “homepage” on the homepage and “single-post” at the single-page level. I think this has to do with the range on the homepage, which is using where to loop through the individual posts, so I understand the context to be within the blog/posts rather than in the context of the homepage when calling the hero.html partial.

Any help would be greatly appreciated.

The “dot” above will not contain the Scratch for the homepage.

Try sending $., or if you really need both, have a look at the dict func and maybe send the scratch as an explicit object.

I am not sure I completely understand your question, but I think you can also attempt to use data and .Data.foo in your template to achieve your goals. You can e.g. put things into a dictionary in a data file indexed by URLs/parts of the URLs and then look them up later.

I do a baby version of this in my personal site where I set the description meta tag in my header partial depending on the type of content. This is a workaround to sections/nodes not having their own consistent metadata store, which is what I think you’re trying to workaround too.

https://github.com/hnarayanan/harishnarayanan.org/blob/master/data/Descriptions.yml

HI @hnarayanan thanks for the input, but I’m already leveraging data for all my section descriptions, but this is not what I’m looking to do. But you provide a good use case for using data, to be sure :slightly_smiling:

@bep Thanks. I’ll give that a shot. Have not used dict at all yet.