squarefrog
squarefrog

Reputation: 4822

How may I manually sort Jekyll pages using yaml?

I'm converting an old site from a PHP CMS to Jekyll, and I'd like to retain the manually ordered pages. Initially, I thought I could rename the files to contain the index, e.g. 01-start-here.markdown, 02-learn-more.markdown etc. This would make things awkward if I ever added a page further down the line.

Ideally I'd like to specify a yaml file containing the page order. For example:

category: basics
pages:
  - start here
  - learn more
  - overview

category: advanced
pages:
  - diving further
  - wrapping up

Is this possible? Looking at the Jekyll site they seem to have a manually ordered site, but I can't quite figure out how.

Additionally, to further compound the issue, I'd like this to be assigned to pages so page.next would automatically move to the advanced category after the last page of basics category.

Upvotes: 1

Views: 198

Answers (1)

David Jacquel
David Jacquel

Reputation: 52809

From Jekyll documentation code

_data/docs.yml

- title: chapter 1
  docs:
  - home
  - page
  - other

- title: Other chapter
  docs:
  - toto
  - etc

In Jekyll, documentation is contained in a _docs collection but this can be easily adapted to works with pages.

Navigation in in _includes/docs_contents.html

<div class="unit one-fifth hide-on-mobiles">
  <aside>
    {% for section in site.data.docs %}
    <h4>{{ section.title }}</h4>
    {% include docs_ul.html items=section.docs %}
    {% endfor %}
  </aside>
</div>

_includes/docs_ul.html

{% assign items = include.items %}
<ul>
{% for item in items %}
  {% assign item_url = item | prepend:"/docs/" | append:"/" %}
  {% if item_url == page.url %}
    {% assign c = "current" %}
  {% else %}
    {% assign c = "" %}
  {% endif %}
  {% for p in site.docs %}
    {% if p.url == item_url %}
      <li class="{{ c }}"><a href="{{ site.url }}{{ p.url }}">{{ p.title }}</a></li>
      {% break %}
    {% endif %}
  {% endfor %}
{% endfor %}
</ul>

The footer prev/next navigation is in _includes/section_nav.html

{% comment %}
Map grabs the doc sections, giving us an array of arrays. Join, flattens all
the items to a comma delimited string. Split turns it into an array again.
{% endcomment %}
{% assign docs = site.data.docs | map: 'docs' | join: ',' | split: ',' %}

{% comment %}
Because this is built for every page, lets find where we are in the ordered
document list by comparing url strings. Then if there's something previous or
next, lets build a link to it.
{% endcomment %}

{% for document in docs %}
  {% assign document_url = document | prepend:"/docs/" | append:"/" %}
  {% if document_url == page.url %}
    <div class="section-nav">
      <div class="left align-right">
          {% if forloop.first %}
            <span class="prev disabled">Back</span>
          {% else %}
            {% assign previous = forloop.index0 | minus: 1 %}
            {% assign previous_page = docs[previous] | prepend:"/docs/" | append:"/" %}
            <a href="{{ previous_page }}" class="prev">Back</a>
          {% endif %}
      </div>
      <div class="right align-left">
          {% if forloop.last %}
            <span class="next disabled">Next</span>
          {% else %}
            {% assign next = forloop.index0 | plus: 1 %}
            {% assign next_page = docs[next] | prepend:"/docs/" | append:"/" %}
            <a href="{{ next_page }}" class="next">Next</a>
          {% endif %}
      </div>
    </div>
    <div class="clear"></div>
    {% break %}
  {% endif %}
{% endfor %}

Upvotes: 2

Related Questions