# Listing Categories by Blog

**URL:** <https://talk.jekyllrb.com/t/listing-categories-by-blog/6477>\
**Category:** Help\
**Created:** [September 22, 2021, 8:52pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477 "2021-09-22T20:52:30Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [September 22, 2021, 8:52pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/1 "2021-09-22T20:52:30Z")

</div>

Hey all,  
I’ve got a website where I essentially have two different blog pages that occasionally share similar content and therefore need a post/category to appear on both pages. Is there any easy way to do this?

I am able to correctly hide posts from one page or the other by using  
{% if post.categories contains ‘Unwanted Category’ %}  
do nothing  
{% else %}  
display posts

However at the top of the blog pages I list the categories. This is where I am having a hard time of only listing certain categories on each blog page.

---

<div class="post-metadata">

**Author:** ![rdyar](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/rdyar/32/710_2.png) [@rdyar](https://talk.jekyllrb.com/u/rdyar)\
**Post date:** [September 23, 2021, 2:27am UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/2 "2021-09-23T02:27:50Z")

</div>

you don’t need to do it as a category - unwantedCategory could be a front matter variable and you could do much the same thing I think.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [September 23, 2021, 5:26am UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/3 "2021-09-23T05:26:33Z")

</div>

You have two groups if you split by display page. Group A and Group B, and each post could be in one or both.

Categories are hierarchical, so setting something to be in category A and B actially makes the URL have A first and then B.

You can use Jekyll post labels like

```auto
---
tags: group_a group_b
---

```

```auto
site.tags.group_a # all matching posts 

```

> **[Posts](https://jekyllrb.com/docs/posts/#tags-and-categories)**
>
> Blogging is baked into Jekyll. You write blog posts as text files and Jekyll provides everything you need to turn it into a blog.

There is no hierarchy or order and it does not affect the output URL.

And you can reference as post.tags and check if a post’s tags including a certain tag

Or more easily get all posts within a certain tag.

The other comment suggests an approach where you make up a value and use that

```auto
---
group_a: true
group_b: false
---

```

---

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [September 23, 2021, 1:07pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/4 "2021-09-23T13:07:48Z")

</div>

I’m still not quite sure how to implement this in my case. I understand how to only show posts with a certain tag, but how do I only show categories belonging to those certain tags? This is the script I am using currently, which does not work.

```auto
<h2>Topics by Post Count</h2>
	<ul>
		{% assign categories_list = site.categories %}
		{% if categories_list.first[0] == null %}
		{% for category in categories_list %}
		<!-- <a href="/Topics/#{{ category | url_escape | prepend site_url }}">{{ category | camelcase }} ({{ site.tags[category].size }})</a> | -->
		{% endfor %}
		{% else %}
		{% for category in categories_list != 'unwantedcategory' %}
		<a href="/topics/#{{ category[0] | url_escape | site_url }}">{{ category[0] | camelcase }} ({{ category[1].size }})</a> |
		{% endfor %}
		{% endif %}
		{% assign categories_list = nil %}
	</ul>

```

---

<div class="post-metadata">

**Author:** ![mmistakes](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/mmistakes/32/2169_2.png) [@mmistakes](https://talk.jekyllrb.com/u/mmistakes)\
**Post date:** [September 23, 2021, 8:32pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/5 "2021-09-23T20:32:54Z")

</div>

Have you tried using Jekyll’s `where` and `where_exp` filters? Those should give you more options in combination with an `assign`.

> **[Liquid Filters](https://jekyllrb.com/docs/liquid/filters/)**
>
> All of the standard Liquid filters are supported (see below).

---

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [September 24, 2021, 1:58pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/6 "2021-09-24T13:58:21Z")

</div>

I have not used the where and where\_exp filters because I would have to list out each category to filter. So every time a new category is added I would have to remember to go back into the code and add it into the where expression.

Is there not a way to essentially have 2 separate blogs within the same site? I think this would be the best approach, and I’ve tried it, but the site.categories variable still picks up all the categories across the site, whereas I need it to only list the categories pertaining to one blog or the other.

---

<div class="post-metadata">

**Author:** ![mmistakes](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/mmistakes/32/2169_2.png) [@mmistakes](https://talk.jekyllrb.com/u/mmistakes)\
**Post date:** [September 24, 2021, 2:24pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/7 "2021-09-24T14:24:20Z")

</div>

Yeah, you’re working against how core Jekyll works. It’s not designed to do 2 blogs in one site.  
`site.categories` does what the tin says… it’s your site’s categories.

---

<div class="post-metadata">

**Author:** ![BillRaymond](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/billraymond/32/5963_2.png) [@BillRaymond](https://talk.jekyllrb.com/u/BillRaymond)\
**Post date:** [September 24, 2021, 7:45pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/8 "2021-09-24T19:45:30Z")

</div>

Technically, you can create two blogs on one site, and there are many examples of how to do that. I created a video series on Jekyll and came up with one of many approaches in the video link at the bottom of this post.

I think what you really want is a URL that looks like this:

`https://www.mysite.com/categories?category=cars`

The result would be a page that displays the blog items you have that talk about the category of cars. Whenever there is a new category, the link changes to that name, and you are good to go. Sounds good, right? Unfortunately, In a Jekyll/static site world, you cannot programmatically figure something out at runtime, so you have to create individual files to handle the routing, but it is pretty easy to do that.

You can create a folder called `categories` and then create a file per each (yes, you still need to do the heavy lifting, but the page would be easy to create).

Create a page in the `categories` folder and call it `cars.md` with whatever front matter you want, like:

```auto
---
layout: default
category: cars
---

```

Now, in the `default` layout (or whatever layout you create), you would have code somewhere in there that looks like this:

```auto
{%- assign posts = site.posts | where_exp: 'post', 'post.category == category -%}
{%- for post in posts -%}
  your html and code here...
{%- endfor -%}

```

If you create a new category and call it `trucks`, add another file in the `category` folder, call it `trucks.md`, and update the front YAML front matter with `category: trucks`.

Jekyll does have a capability referred to as collections, where you can create a grouping of any data, like a second blog, for example. Here are the official docs:

> **[Collections](https://jekyllrb.com/docs/collections/)**
>
> Collections are a great way to group related content like members of a team or talks at a conference.

I think the following thread covers a lot of your questions in a slightly different context, but still what I think you are asking for:

> [@Advice for filtering collection with routes](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886):
>
> Hey there! I’m not exactly new to Jekyll, but never had to work on this sort of desired structure. Apologies if I’m missing some obvious functionality. If there is a way to achieve the following structure, how would you go about it in the cleanest, best practices kind of way. Let’s say I have a large collection of places. Each of the place has two categories assigned, type and location. For example: title: Cool Brewery type: Bar location: West I’d like to filter using routes, so: /place…

Here is a video I created a while back with **one way** you can have multiple blogs on a single site. I do not think this is what you want, but it could be helpful! It is part of a training series, so it assumes you have a Jekyll site set up locally with the default minima theme.

[![](https://canada1.discourse-cdn.com/flex030/uploads/jekyllrb/original/2X/4/4a83f4b275a325e45860bdf5c0e6a12c0d5cc416.jpeg "Up and Running with GitHub Pages, Part 6, Multiple Jekyll Blogs and Feeds") ](https://www.youtube.com/watch?v=iIBkOWY5aAA)

---

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [October 12, 2021, 8:03pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/9 "2021-10-12T20:03:28Z")

</div>

I think I am close to getting what I want. I am using categories like normal, but have added two different tags to each posts’ front matter.I am trying to create a list of categories belonging to posts in each tag, tag “A,” or tag “B.”

```auto
							<h2>Topics by Post Count</h2>
							<ul>
								{% assign categories_list = site.categories %}
								{% if categories_list.first[0] == null %}
								{% for category in categories_list %}
								<!-- <a href="/Topics/#{{ category | url_escape | prepend site_url }}">{{ category | camelcase }} ({{ site.tags[category].size }})</a> | -->
								{% endfor %}
								{% else %}
								{% for post in site.tag.['B'] %}
								<a href="/topics/#{{ category[0] | url_escape | site_url }}">{{ category[0] | camelcase }} ({{ category[1].size }})</a> |
								{% endfor %}
								{% endif %}
								{% assign categories_list = nil %}
							</ul>

```

However, the code above doesn’t seem to be doing anything. Any guesses as to why?

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 13, 2021, 2:12pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/10 "2021-10-13T14:12:04Z")

</div>

> [@wvcaudill2](#):
>
> `site.tag.['B'] `

This is bad code. tags not tag

And either

```auto
site.tags.B

```

Or

```auto
site.tags['B']

```

Not both.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 13, 2021, 2:22pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/11 "2021-10-13T14:22:53Z")

</div>

> [@wvcaudill2](#):
>
> ```auto
> {% assign categories_list = site.categories %}
> {% if categories_list.first[0] == null %}
> {% for category in categories_list %}
> 
> ```

Try simpler code first like without null check and just printing the category name and then if that works you can add more stuff.

The way you iterate over categories is not correct.

It is a hash which gets unpacked as a pair of category name and posts in the category

See `c[0]` and `c[1]` and related code in this guide

> **[Categories](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/jekyll/liquid/posts/categories.html)**
>
> A collection of code snippets and CLI guides for quick and easy reference while coding

---

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [October 21, 2021, 8:40pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/12 "2021-10-21T20:40:24Z")

</div>

Even following the linked guide I am unable to get a list of tags belonging to Blog B. Does this method only work for categories maybe?

```auto
								{% for c in site.tags['Blog B'] %}
									{{ c[0] }}
								{% endfor %}

```

Liquid Exception: 0 is not a symbol nor a string

With this code, I am trying to get all categories associated with tag “Blog B”

Or if there truly isn’t a way to do this, could I just find a way to list only the categories belonging to “Blog B” manually?

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 22, 2021, 1:29pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/13 "2021-10-22T13:29:10Z")

</div>

Try

```auto
{{ c | inspect }}

```

So you can see what c contains.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 22, 2021, 1:31pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/14 "2021-10-22T13:31:34Z")

</div>

Did you definitely use 0 as a number and not O as a letter?

```auto
{{ c[0] }} {{ c[1] }}

```

---

<div class="post-metadata">

**Author:** ![wvcaudill2](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/wvcaudill2/32/3919_2.png) [@wvcaudill2](https://talk.jekyllrb.com/u/wvcaudill2)\
**Post date:** [October 22, 2021, 1:42pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/15 "2021-10-22T13:42:06Z")

</div>

It appears to contain the HTML of the current page.

I confirmed the use of 0 as a number.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 23, 2021, 2:34pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/16 "2021-10-23T14:34:55Z")

</div>

I’d say then reduce your scenario to be more generic and then customize after.

So firstly take out spaces of tags and use hyphen instead.

```auto
tags: blog-b blog-c

```

* * *

If you used spaces…

```auto
tags: blog b blog c

```

That becomes `blog, b, blog, c`, as 4 items

Unless you are explicit

```auto
tags: ["blog b", "blog c"]

```

* * *

Secondly you can try a more generic piece of code which works elsewhere.

> **[Tags](https://michaelcurrin.github.io/coding-blog/tags.html)**
>
> My blog of experiences and advice around coding

```auto
{% assign tags = site.tags | sort %}

{% for tag in tags %}
<h3>#{{ tag[0] }}</h3>

{% for post in tag[1] %}
- [{{ post.title }}]({{ post.url | relative_url }})
{% endfor %}
{% endfor %}

```

Which is like doing this for each tag.

```auto
assign tag = site.tags.abc
tag[0]
tag[1]

```

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [October 23, 2021, 2:37pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/17 "2021-10-23T14:37:49Z")

</div>

And your `c` value (or my `tag` value) should contain more than the HTML that you said.

It should be something like

```auto
[
  "Blog B",
  [<post 1>, <post 5>, ...]
]

```

---

<div class="post-metadata">

**Author:** ![fabiomux](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/fabiomux/32/2656_2.png) [@fabiomux](https://talk.jekyllrb.com/u/fabiomux)\
**Post date:** [October 27, 2021, 1:53pm UTC](https://talk.jekyllrb.com/t/listing-categories-by-blog/6477/18 "2021-10-27T13:53:48Z")

</div>

> Is there not a way to essentially have 2 separate blogs within the same site?

The simplest way is to use the first category in each post as blog name and alter the global permalink to output the pages taking categories into account. You may arrange the different content in two different _\_posts_ subfolders, one for each blog, just to make everything well organized.

You might also create collections of authors as the example in this page show: [GitHub - cameronmcefee/jekyll-authors: Example of using authors in Jekyll posts](https://github.com/cameronmcefee/jekyll-authors)

At this point to render different categories for different blogs, you can create two different layouts or consider within your single layout the nature of your post reading the first category or the author specified in the front matter. For every blog create a list of categories to embed, this list can be a _\_data_ file for each blog, or just a variable embedded in the layout (not recommended though), the layout will choose which list to read from.
