How to adjust Jekyll post order?
Asked Answered
S

4

45

I have started a Jekyll based blog with a theme jekyll-now. I am new to Jekyll and how it operates (especially Liquid). I understand that new posts need to be as follows: 2014-10-04-Hello-World.md. But I really don't understand how I could order these.

My first thought is that they order by date so two posts on the same date would order randomly. But is this not the case? Is there a way of ordering posts chronologically. OR at least having a post archive page?

Stumpage answered 4/10, 2014 at 19:49 Comment(0)
B
53

There is an example in the official Jekyll documentation how to create a basic post archive page:
Displaying an index of posts

Bonus: For a prettier archive page (grouped by year or year/month), see this answer.


You're right, I can't find anything in the docs where it says how the posts are ordered, but in fact Jekyll does order them chronologically, with the most recent post first (you can see this if you try the examples I linked above).

To sort them the other way (the oldest post first), you can use the reversed keyword, according to the Liquid documentation:

{% for post in site.posts reversed %}

However, I don't know how two posts on the same date are ordered, because I don't write that much posts, so I never had that problem :-)
You have to try that yourself.

Bes answered 5/10, 2014 at 9:26 Comment(5)
Thanks this did sort the problem. It's a shame I can't order by time as two posts on the same day seem to order however they like! I was looking to create an archive so that's really helpful.Stumpage
You can sort by time, if you had bothered to read the answers. ;)Collete
Most recent post first? That's not chronological order. That's reverse chronological order.Lead
Two posts with the same date will still have different timestamps, so they'll sort correctly.Gujral
Jekyll filters allow you to do a bunch of things like sort by title if you want too: jekyllrb.com/docs/liquid/filtersFormation
S
35

Just faced the same problem and solved with this solution: https://groups.google.com/forum/#!topic/jekyll-rb/8QCIzevauSU

Add a date field to the YAML Front Matter of a post, like so:

date: 2010-09-15 14:40:45

e.g. if you have 2 posts on 2014/12/31, you can add date: 2014-12-31 00:30:00 to latest_post.md, and date: 2014-12-31 00:10:00 to older_post.md.

You can add time zone (e.g. date: 2014-12-31 00:10:00 +08:00) if needed

Suggest answered 31/12, 2014 at 11:15 Comment(1)
Great to learn the date field is optional! (I've been manually keeping that in sync with the file name... duh :-(Empathic
M
14

I want to document my struggle into this post so it may help other users. You need to do two changes:

  1. Open your posts and add weight. e.g., weight:100
  2. Open your html file for the menu where you want the sorted posts. For Java/J2EE menu I have java.html file at the root path of my project.

Then, add the {% assign pages_list = pages_list | sort:"weight" %} line as shown in the below code. This will sort by weight.

{% for category in site.categories %} 
  {% if category[0] contains 'java' %} 
    <h3 id="{{ category[0] }}-ref">{{ category[0] | join: "/" }}</h3>
    <ul>
      {% assign pages_list = category[1] %}  
      {% assign pages_list = pages_list | sort:"weight" %}  
      {% include JB/pages_list %}
    </ul>
  {% endif %}
{% endfor %}
Maharajah answered 16/5, 2015 at 10:45 Comment(0)
B
0

Jekyll just string-compares post paths when sorting, which is why the date format is year-month-day. Posts are internally also collections and you can see the sorting being invoked in reader.rb:

# Sorts posts, pages, and static files.
def sort_files!
  site.collections.each_value { |c| c.docs.sort! }
  site.pages.sort_by!(&:name)
  site.static_files.sort_by!(&:relative_path)
end

So it's using generic ruby methods to sort and implements the comparator in document.rb:

# Compare this document against another document.
# Comparison is a comparison between the 2 paths of the documents.
#
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
#   equal or greater than the other doc's path. See String#<=> for more details.
def <=>(other)
  return nil unless other.respond_to?(:data)

  cmp = data["date"] <=> other.data["date"]
  cmp = path <=> other.path if cmp.nil? || cmp.zero?
  cmp
end

Which means it first compares the dates and only checks the text if needed.

The date is special only if it somehow wasn't found (no metadata). For drafts it falls back to the file modification time, for the rest to the site time.

So if you want to force a different ordering of posts from the same day, craft the start of the title in the filename to alphabetically sort first. Eg. 2020-01-01-a.md will come after 2020-01-01-b.md if you're listing posts in descending order.

Beanery answered 23/8, 2020 at 12:42 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.