How to exclude post with certain tags to be displayed on the homepage

I want to hide posts with a “company-updates” tag from the homepage. They are ok to be displayed on all other pages, except for the homepage.

Handlebars are a bit limited in syntax and how they handle conditional statements. There are several solutions:

  1. Add .hbs helper in the Ghost core to check for the “company-updates” tag and use it in the theme. My least preferred option, I don’t want to mess with backend. It has to be embedded in the theme file.
  2. Create JS file that hides posts with the specified tag. Now rendering all posts and then hiding them on the client side is not the ideal solution. It will load the page with additional script , decrease performance and might cause issues.
  3. Modify the index.hbs file with the working code, don’t touch anything else. This is my preferred option.

What I have tried to modify in index.hbs file:

<div class="post-feed">
    {{#is "home"}}
        {{#foreach posts}}
            {{#unless (has tag slug="newsletter")}}
                {{> "post-card"}}
            {{/unless}}
        {{/foreach}}
    {{else}}
        {{#foreach posts}}
            {{> "post-card"}}
        {{/foreach}}
    {{/is}}
</div>

Second option:

<div class="post-feed">
    {{#is "home"}}
        {{#foreach posts}}
            {{#unless primary_tag.slug "newsletter"}}
                {{> "post-card"}}
            {{/unless}}
        {{/foreach}}
    {{else}}
        {{#foreach posts}}
            {{> "post-card"}}
        {{/foreach}}
    {{/is}}
</div>

None of them work. How to properly check for a condition on a certain tag and exclude it from indexing on the homepage?

Agreed, don’t do #1 or #2.
#3 is close, but (1) you’re using the #unless helper wrong - it’s just checking a boolean. You wanted #has or #match instead. But (2) there’s a better way to do this anyway.

Here’s how you should really do it, since this theme isn’t making a #get request.

What you want to do here is to create a routes.yaml file that excludes the posts from the / route, and puts them somewhere else. See “Filtering Collections” in the documentation found here: Ghost Themes - Dynamic URLs & Routing
Note that everything needs somewhere to be, so you’re going to want a collection with filter: tag:-newsletter and a second one with filter: tag:newsletter

(An aside, for users of the Source theme, which actually has a #get to populate the homepage: You need to find the get request and add a filter parameter to it. See the #get documentation. Ghost Handlebars Theme Helpers: get Routing doesn’t fix the problem for Source users, because #get ignores routing.)

1 Like

Thank you, that’s awesome! It helped with a single tag. I’m trying to hide multiple tags and my code doesn’t work:

routes:

collections:
  /:
    permalink: /{slug}/
    template: index
    filter: tag:-newsletter+tag:-"the company newsletter"
  
  /newsletter/:
    permalink: /newsletter/{slug}/
    template: newsletter
    filter: tag:newsletter

  /the-company-newsletter/:
    permalink: /the-company-newsletter/{slug}/
    template: the-company-newsletter
    filter: tag:"the company newsletter"

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

My posts are tagged “the company newsletter”. Is that tag containing spaces and multiple words referenced correctly?

it’s using the slug, which is probably the-company-newsletter
I /think/ you can filter instead as tag:-[newsletter,the-company-newsletter], which is slightly more succinct, but either should work, as long as you have the newsletter slug.

2 Likes

That’s great, thank you!

1 Like