Excluding a category from the blog homepage

For excluding posts from a certain category on the homepage, I found this. But not sure if I need to add this to layouts/index.html or layouts/_default/list.html. I tried both but got errors. I may have inserted them in the wrong place.

Here’s the code for the index file:

It would be in layouts/index.html. Can you share the code that you tried which errored out?

It was linked in the earlier post - Exclude a category from list.html - support - HUGO

I put the code after {{ if eq .Type "post" }}

I would filter further up, prior to the grouping. Either when setting $posts or right after-- probably by adding and to your existing where.

1 Like

Agreed with @jsonbecker. You should filter even before you begin to range on it.

So just add {{ if not (in .Params.categories "Blog") }} just after the <h3> line or after the <main class...>?

BTW what’s the syntax if I want to add an 'and to the where statement?

@amit Tried it at both places but threw up a parsing error for both.

I have managed to get it working, but the other way around. Basically, display posts with specific categories, not exclude them. It should be possible but just can’t think of a simple way.

I did this alteration on the default homepage post listing. My use case is I copy all my Letterboxd reviews to my Micro.blog but I don’t want them to show up on the homepage (because I watch a lot of movies and don’t want them to clog up the view).

It seems to work at first, but it actually only filtered out the first four posts. Once it hits a post that passes the “if not” test, the subsequent Letterboxd reviews show on the page. :sweat:

<ul id="post-list">

{{ if or .IsHome .Site.Params.paginate_categories }}
	{{ $paginator := .Paginate (where .Site.Pages.ByDate.Reverse "Type" "post") }}
	{{ $list := $paginator.Pages }}
	{{ range $list  }}
		{{ if not (in .Params.categories "Letterboxd") }}
		{{ partial "post-item.html" . }}
		{{ end }}
	{{ end }}
{{ else }}
	{{ $list := where .Site.Pages.ByDate.Reverse "Type" "post" }}
	{{ range $list  }}
		{{ if not (in .Params.categories "Letterboxd") }}
		{{ partial "post-item.html" . }}
		{{ end }}
	{{ end }}
{{ end }}


{{ $paginator := .Paginate (where (where .Site.Pages.ByDate.Reverse "Type" "post") ".Params.categories" ne "Letterboxd") }}

You do not want to filter after paginating or after doing a range. You want to filter out these posts at the first point you’re developing what set of pages are valid for your collection.

In @pratik’s case, something like this

{{ $posts := where (where .site.RegularPages "Type" "post") ".Params.categories" eq "Motherboards" }}

Would work. Or something quite similar.

I believe this doesn’t work as the categories param is a list. I got this working. Doing it as a negative is trickier.

{{ $posts := where site.RegularPages "Type" "post" }}
{{ $posts = where $posts ".Params.categories" "intersect" (slice "dev" "sample") }}

cc @pratik

Thanks! This works for now. I tried all sorts of different permutations for the previous suggestion and it just doesn’t seem to want to work. It’s a bit of a pain having to jump in and update every time I add a category, and doesn’t work well with putting posts in multiple categories. Would love to see a plug-in that simplifies this. :slight_smile:

Hugo’s symdiff function returns the symmetric difference between two collections. That’s just a fancy way to say: “give me the things that are in either of these collections but not in both”.

So, if you have all posts in one collection, $posts, and posts from the category you want to exclude in another collection, $hidden_posts, you can get all posts sans excluded posts with $posts | symdiff $hidden_posts. Something like this:

{{ $posts := where site.Pages "Type" "post" }}
{{ $hidden_posts := where $posts "Params.categories" "intersect" (slice "Hidden") }}
{{ $posts = $posts | symdiff $hidden_posts }}

In the example above, $posts will contain all posts except posts in the category Hidden .


Nice! Thank you, @sod. Learnt a new thing. This should do what @pratik needs.

Replace line 2 in layouts/index.html with this code block that Sven shared. Place categories that you want to exclude in second line next to slice (for example, dev, tech in the example),

{{ $posts := where site.Pages "Type" "post" }}
{{ $hidden_posts := where $posts "Params.categories" "intersect" (slice "dev" "tech") }}
{{ $posts = $posts | symdiff $hidden_posts }}

I have tested this, works as expected.


This is fantastic. Thanks, @sod, @amit and @jsonbecker. This is why I love Micro.blog. You get to learn new things every day.

1 Like

You are all rocket scientists as far as I am concerned, or Wizards! I like wizards better!

Resurfacing this topic a bit, anyone ever done changes in the theme, to also remove the category and it’s posts from listing in the archives page? I was trying with some of the code provided here, but I could not. I am basically trying to implement an RSS-Club on my MB. Welcome to RSS Club | daverupert.com

You may ask @jsonbecker, who has filtered his Archive page to only display longform posts.

Thanks! If I look at such code, I can make it work for me!

You’ll want to edit layouts/_default/list.archivehtml.html using the same technique for the range there I think. The way I do my page is different and more complex, but I’m 95% sure that template (which is a default template) is where the normal archive page is made from.