# How to filter posts by date, number of comments or number of words in a post?

**URL:** <https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715>\
**Category:** Help\
**Created:** [October 12, 2022, 10:54am UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715 "2022-10-12T10:54:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![WarmingZ](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/warmingz/32/4910_2.png) [@WarmingZ](https://talk.jekyllrb.com/u/WarmingZ)\
**Post date:** [October 12, 2022, 10:54am UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715/1 "2022-10-12T10:54:05Z")

</div>

Hello everyone, I want to make a filter for my messages.  
I already made buttons for this:

```nohighlight
<div id='sorters'>
Sort by:
<span id="by_date" onclick="sort_by_date();" class="sorter active">date</span>
|
<span id="by_comments" onclick="sort_by_comments();" class="sorter">comments</span>
|
<span id="by_length" onclick="sort_by_length();" class="sorter">length</span>
</div>

```

But I don’t know how to write JS functions to display posts for my parameters.  
I tried to use a simple string replacement via the `innerHTML` function, but it doesn’t work because you just have to copy entire sections of code.

I know how to use Jekyll Filters, but I don’t know how to display them on a button. Please help me solve the problem

---

<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:** [October 12, 2022, 11:58pm UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715/2 "2022-10-12T23:58:30Z")

</div>

this is definitely a JS thing, there are probably multiple ways to do this. You can probably find an example of this type of thing just not with Jekyll, and then you just have jekyll output things like you need.

This is not a trivial thing, though it shouldn’t be too difficult. Not something one of us is likely to post a full working example of but who knows.

One idea is you can use jekyll to create a json file of all your posts, then you could use JS to display those and then you would be able to filter them easily I think.

---

<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:** [October 13, 2022, 10:51pm UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715/3 "2022-10-13T22:51:46Z")

</div>

As @rdyar points out, you are definitely heading into JavaScript territory. Here is a [starter example](https://www.w3schools.com/howto/howto_js_sort_table.asp) I found on W3Schools to sort data on a page using tables. If you want to go this route, I suspect you will want to code your page in a very specific way with HTML which is easy enough to do with Jekyll. For JavaScript, I suspect Stack Overflow would be a better place to ask the question.

That said, you could start to run into problems with JavaScript if you have too many posts and start paginating the posts. For example, imagine having a web page load, say, 25 posts out of 100. The user has to click the _next_ button to open the next 25 and so on. Now, JavaScript is not as useful because all the content is not on one page.

A way to handle this with Jekyll is to create multiple files, each one displaying the content by a defined sort. Here is a way to accomplish what you are looking for with reusable code.

## 🗃 Create files that represent each sort order

In my example, I am going to put all my sorting options into a folder. If the user visits [https://myjekyllsite.com/myposts](https://myjekyllsite.com/myposts), the index file displays. However, I could also link to [https://myjekyllsite.com/myposts/bylength](https://myjekyllsite.com/myposts/bylength) and get a list of posts sorted by the size of the content instead.

Create a folder under the root Jekyll folder and call it `myposts` and then add a file that represents each sort order, like this:

```auto
./myposts/index.html (displays the default Jekyll sort order)
./myposts/bydate.html (sorts oldest to newest)
./myposts/bylength.html (sorts from the shortest to the longest)

```

^^ Note, those could be markdown files instead of HTML

## 〰 Custom YAML `sortby` element

Open each file and add the YAML front matter as listed below.

`./myposts/index.html` (no sortby)

```auto
---
layout: myposts
---
<p>Sort by Jekyll default

```

`./myposts/bydate.html`

```auto
---
layout: myposts
sortby: date
---
<p>Sort by date

```

`./myposts/bylength.html`

```auto
---
layout: myposts
sortby: length
---
Sort by length

```

## 🧑‍💻 Create the `myposts` layout file

The files you just created will reuse the same exact layout, so you are just creating a holding place for the content. If you do not have a folder called `_layouts` in your Jekyll website folder, create it and then create a file called `myposts.html` as follows:

./\_layouts/myposts.html

```auto
---
layout: default
---

{{content}}

{%- assign sortBy = page.sortby -%}
{%- case sortBy -%}
    {%- when "date" -%}
        {%- assign posts = site.posts | sort: 'date' -%}
    {%- when "length" -%}
        {%- assign posts = site.posts | sort: page.content.size -%}
    {%- else -%}
        {%- assign posts = site.posts -%}
{%- endcase -%}

<h2>List of posts</h2>
{% for post in posts %}
    <p></p><strong>{{post.title}} (length: {{post.content.size}}) / (date: {{post.date}})</strong>
{% endfor %}

```

With Jekyll running, visit each of those `index.html`, `bydate.html`, and `bylength.html` pages and you will notice they display the content using the same exact layout, but are sorted differently.

## 📄 Code walkthrough

In the `myposts.html` layout file, you first get the `sortby` YAML front matter from the loading page (in our case, `index.html`, `bydate.html`, and `bylength.html`).

Next, you create a `case` statement that defines the list of posts you want, along with a filter that defines how you want them sorted. If there is no `sortby`, then the code uses Jekyll’s default sort order, which is typically newest-\>oldest. That is why I did not create a `sortby` in the `index.html` file. You can of course do whatever you want and add a `sortby` element to the index page if you want.

The last bit of code displays the lists of posts based on the `sortby` method you defined. In my example, I created some helper code to display the title of the post along with the length (content size) of each post and the date so you can verify the titles sort as you would expect.

## 💡 Tips

- In the layout file, you should add some `hrefs` or buttons that link to the various sorting options.

- You could move all that the code from `{%- assign sortBy = page.sortby -%}` to `{%- endcase -%}` into an `include` file in the `./_includes` folder. That way you can re-use the code for something else.

- I did not include an example for _comments_ as you requested because I am unsure how you would want to handle that and Jekyll does not have built-in support for comments.

- You can get fancy and provide multiple sort types (by date, by length, descending) in your YAML front matter, but that will of course add a lot more complexity.

- You can create more pages with more YAML front matter, like `sortby: lengthdescending` and add more `case` statements for ascending and descending sort orders. Again, I suggest you move that `case` statement to an include file if the code gets too bulky.

- When you sort with Liquid, it is usually smallest-\>greatest or alphabetical order. For example, in my code example, if you visit the `bylength.html` page, it will display the post with the least amount of content first. If you want to reverse that order, use the `reverse` filter, like this:  
`{%- assign posts = site.posts | sort: page.content.size | reverse -%}`

I hope this helps!

---

<div class="post-metadata">

**Author:** ![WarmingZ](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/warmingz/32/4910_2.png) [@WarmingZ](https://talk.jekyllrb.com/u/WarmingZ)\
**Post date:** [October 14, 2022, 8:22am UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715/5 "2022-10-14T08:22:16Z")

</div>

Thanks so much Bill for such a comprehensive answer! It’s not the first time you’ve helped me, thank you very much

---

<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:** [October 14, 2022, 4:14pm UTC](https://talk.jekyllrb.com/t/how-to-filter-posts-by-date-number-of-comments-or-number-of-words-in-a-post/7715/6 "2022-10-14T16:14:26Z")

</div>

No problem! I hope the solution works for you!
