# Sort posts by updated and published date

**URL:** <https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789>\
**Category:** Uncategorized\
**Created:** [December 8, 2021, 10:36am UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789 "2021-12-08T10:36:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [December 8, 2021, 10:36am UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789/1 "2021-12-08T10:36:05Z")

</div>

Any ideas on how to do sort posts by the date it was published, but use a front matter property if that’s populated instead?

Some of our blog posts get updated occasionally and become relevant again. These posts should be appear on top with the newest posts. We don’t want to pretend that the post was only recently published, so I added a `updated` front matter field for the date on which it was last updated.

Now I’d like to sort the posts chronologically by that `updated` value, but use the publish date instead if the post hasn’t been updated after publishing. Simply sorting by `published` and then by `updated` doesn’t work—that would put all updated posts before all other posts that haven’t been changed, even if they haven been published after all the updated posts have had a change.

Of course I could populate the `updated` field with the `published` value for all posts, but that would require editors to change both fields if they don’t want to use the default value (‘now’), which is prone to mistakes.

---

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [December 8, 2021, 10:46am UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789/2 "2021-12-08T10:46:08Z")

</div>

Ah I have an idea: instead of adding an `updated` field, I could add an `originally_published` field. Then I can simply change the publish date upon updates, sort by that and use the `originally_published date` if available.

---

<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:** [December 8, 2021, 11:02pm UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789/3 "2021-12-08T23:02:07Z")

</div>

I am trying to understand your question here. Jekyll will always sort your list of posts descending, by the `date` field, so the latest post shows first.

Each post has front matter, like this:

```auto
---
title: My post
date: 12-01-01
layout: post
---
This is my blog post...

```

The following code will always sort the list of posts descending using that `date` field, so the last post is the latest:

```auto
{% for post in site.posts %}
  <p><a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}

```

If you want to sort by some other field, then absolutely, you can use the front matter as you propose. Here is what that might look like using your example:

```auto
---
title: My post
date: 12-01-21
last_updated: 12-08-21
layout: post
---
This is my blog post...

```

And you would sort this way:

```auto
{% assign posts = site.posts | sort: 'last_updated' | reverse %}
{% for post in posts %}
  <p><a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}

```

Of course if you can remove the `reverse` option to sort ascending.

Hope that helps!

---

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [December 9, 2021, 8:12am UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789/4 "2021-12-09T08:12:50Z")

</div>

Ah sorry, I see I did a poor job explaining the challenge! Here’s what I had in mind:

1. All posts have a `date`, indicating when they were first published
2. The archive is sorted chronologically, with the most relevant posts at the top. Right now relevance is defined by recency: the newest posts appear first.
3. Some posts get changes. Only these posts have a `updated` front matter property with the date of the last update as a value.
4. **Posts should be sorted by their `updated` value, but since that value isn’t available for all posts, the `date` value should be used as a fallback.**
5. This should result in posts updated today appearing at the top of the archive and posts updated last month appearing among the posts published last month.

That said, I realized that updating a post doesn’t always make them relevant again (f.e. when we correct a mistake). So instead I added another front matter field: `pin`. Posts with `pin: true` appear before all other posts. The code for that is simple:

```auto
{% assign groups = site[page.collection] | where_exp: "item", "item.path contains '/posts/'" | reverse | group_by: 'pin' | reverse %}
{% for group in groups %}
  {% for post in group.items %}
    {% include post_preview.liquid post = post %}
  {% endfor %}
{% endfor %}

```

(We use collections to manage content in different languages, so `site[page.collection] | where_exp: "item", "item.path contains '/posts/'"` just means all posts on the site in the archive page’s language.)

---

<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:** [December 10, 2021, 5:35pm UTC](https://talk.jekyllrb.com/t/sort-posts-by-updated-and-published-date/6789/5 "2021-12-10T17:35:12Z")

</div>

I am thinking you are getting pretty advanced with this. What are your thoughts on performing multiple queries? You can create them as part of the business logic in an include page so you do not have to write it out all the time. I think it will also help reduce complexity.
