Search code examples
handlebars.jsghost-blog

Include handlebars partials when they exist based on context in Ghost


I've got a customized theme for Ghost. I nave a guest author once on a while. I'd love the ability to include any number of custom links to the authors page for each author.

I'm aware of the authors-{{slug}}.hbs convention I could use to create a complete custom page for each author, but that's a nightmare to maintain.

Instead I was trying to try to include a partial when it exists. According to the handlebars docs the {{#> partial }} should work. But that works when I know the exact name of the partial.

I need the name of the partial to be dynamic based on the context. In my case the ghost slug for the author. According to the handlebar docs I need to pass in a function...

enter image description here

I tried a few ways, but gscan dislikes all of them:

 {{#> (concat "partials/socials-" slug) }}
 {{#> (concat "partials/socials-" (lookup . 'slug')) }}
 {{#> concat "partials/socials-" (lookup . 'slug') }}
 {{#> "partials/socials-{{slug}}" }}
 {{#> partials/socials-{{slug}} }}

All give me:

Checking theme compatibility...

Your theme has 1 error!
----

Errors
------
Important to fix, functionality may be degraded.

- Error: Templates must contain valid Handlebars
Files: author.hbs

Solution

  • Have you used content blocks before? They're a way to re-use template code but still allow for customisation, it's a method used in Casper which you've forked from. Check out these lines here in page.hbs: https://github.com/jessehouwing/jessehouwingnl-Casper/blob/customized/page.hbs#L58-L65

    as well as this line shown in default.hbs: https://github.com/jessehouwing/jessehouwingnl-Casper/blob/customized/default.hbs#L127

    What you could do is create a custom author template that inherits the existing author.hbs template. For this example I'm going to create a custom author page for the author 'ghost' by creating author-ghost.hbs:

    {{!< author}}
    
    {{#contentFor "links"}}
      <ul>
        <li><a href="https://example.com">Example link</a></li>
        <li><a href="https://example.com">Example link</a></li>
        <li><a href="https://example.com">Example link</a></li>
      </ul>
    {{/contentFor}}
    

    The above code inherits author.hbs and creates a block called links. Then in the original author.hbs template we can add the block reference to where we want the contents of the block to appear:

    {{{block "links"}}}
    

    Not only will this insert the code in the custom author template, but it'll also gracefully fallback to no output if there isn't a custom author template for the author.

    Hope this helps!