How to change the default order pages in Jekyll?

My blog is built with Jekyll on Github. In the navigation bar, the default order is Pages, Messages, About, Archives. I want to change the list to Pages, Archives, About, Messages. What should I do?

I think it is related to the code below

{% assign pages_list = site.pages %}

I think site.pages is what I should change, but I don't know how.


Solution 1:

You can create custom order of your menu items like this:

  1. In your pages front matter add the order field (you can name it as you prefer)
    ---
    layout: default
    published: true
    title: Page title
    order: 1
    ---
    
  2. When getting pages, apply the 'sort' filter
    {% assign sorted_pages = site.pages | sort:"order" %}
    {% for node in sorted_pages %}
      <li><a href="{{node.url}}">{{node.title}}</a></li>
    {% endfor %}
    

You'll end up with an ordered (ASC) list of pages, based on the 'order' field value you add to each page.

Solution 2:

Update: Some ordering functionality seems to have been added to Jekyll: https://github.com/plusjade/jekyll-bootstrap/commit/4eebb4462c24de612612d6f4794b1aaaa08dfad4

Update: check out comment by Andy Jackson below – "name" might need to be changed to "path".

This seems to work for me:

{% assign sorted_pages = site.pages | sort:"name" %}
{% for node in sorted_pages %}
  <li><a href="{{node.url}}">{{node.title}}</a></li>
{% endfor %}

name is file name. I renamed pages to 00-index.md, 01-about.md etc. Sorting worked, but pages were generated with those prefixes, which looked ugly especially for 00-index.html.

To fix that I override permalinks:

---
layout: default
title: News
permalink: "index.html"
---

Sadly, this won't work with custom attributes, because they are not accessible as methods on Page class:

{% assign sorted_pages = site.pages | sort:"weight" %} #bummer

Solution 3:

The order of your navbar menu is determined by the HTML template in _layout (which may be pulling in HTML fragments from _includes.

It sounds like your navbar is being programatically generated from the list of pages provided in site.pages using the liquid code

{% assign pages_list = site.pages %}

If you have only a small number of pages, you may prefer to just write the list out manually. site.pages is Jekyll's alphabetical list of all pages. Nothing stops you from just hardcoding this instead:

 <div class="navbar" id="page-top">
      <div class="navbar-inner">
        <div class="container">
          <a class="brand" href="/">EverCoding.net</a>
          <ul class="nav">
            <li><a href="/pages.html">Pages</a></li>        
        <li><a href="/archive.html">Archive</a></li>
        <li><a href="/about.html">About</a></li>
        <li><a href="/messages.html">Messages</a></li>

Whereas I'm guessing at the moment you have that list generated programmatically, perhaps by following the way Jekyll-bootstrap does with liquid code:

<div class="navbar">
      <div class="navbar-inner">
        <div class="container">
          <a class="brand" href="{{ HOME_PATH }}">{{ site.title }}</a>
          <ul class="nav">
            {% assign pages_list = site.pages %}
            {% assign group = 'navigation' %}
            {% include JB/pages_list %}
          </ul>
        </div>
      </div>
    </div>

The liquid code in this second example is handy if you really want to determine the menu each time, but if you have a static menu in a static order you are probably best coding it by hand as in my first example, rather than modifying the liquid code to sort.

If you could link to the Jekyll source, rather than the published blog, we could be more specific.