Post Navigation

Today’s project was to get next and previous hyperlinks working for my commonplace book. Jekyll and Liquid have nice built in functionality for generating next and previous links without having to hard code anything. I added the following, pulled from David Elbe’s site, and it worked immediately:

<h4>Previous Entry <span style="float:right;">Next Entry</span></h4>

<div class="postNavigation">
  {% if page.previous.url %}
    <a class="prev" href="{{page.previous.url}}">« {{page.previous.title}}</a>
  {% endif %}

  {% if page.next.url %}
    <span style="float:right;"><a class="next" href="{{page.next.url}}">{{page.next.title}} »</a></span>
  {% endif %}
</div>

However, this code does not account for post categories, and so I quickly discovered that the next and previous buttons would take me to other posts on the website (such as those under blog or log). After some sleuthing, and quite a bit of trial and error, I arrived at the following solution, adapted from the solution at Adam Clarkson’s site.

First, I created a new generator, WithinCategoryPostNavigation.rb, and added it to a new subdirectory _plugins:

module Jekyll
  class WithinCategoryPostNavigation < Generator
    def generate(site)
      site.categories.each_pair do |category, posts|
        posts.sort! { |a,b| b <=> a}
        posts.each do |post|
          index = posts.index post
          next_in_category = nil
          previous_in_category = nil
          if index
            if index < posts.length - 1
              previous_in_category = posts[index + 1]
            end
            if index > 0
              next_in_category = posts[index - 1]
            end
          end
          post.data["previous_in_category"] = previous_in_category unless previous_in_category.nil?
          post.data["next_in_category"] = next_in_category unless next_in_category.nil?
        end
      end
    end
  end
end

Jekyll knows to run .rb files in the _plugins folder by default. Next, I just had to tweak the Liquid in my commonplace entry layout to the following:

<h4>Previous Entry <span style="float:right;">Next Entry</span></h4>

<div class="postNavigation">
  {% if page.next_in_category != nil %}
		<a href="{{page.next_in_category.url}}" class="next-link">« {{page.next_in_category.title}}</a>
  {% endif %}

	{% if page.previous_in_category != nil %}
    <span style="float: right;"><a href="{{page.previous_in_category.url}}" class="previous-link">{{page.previous_in_category.title}} »</a></span>
  {% endif %}
</div>

I had a heck of a time getting the next and previous links to display and link correctly. For some reason, Clarkson’s solution has page.next_in_category link to the next older post, while page.previous_in_category links to the next newer post. The solution above involved swapping next and previous in the .rb file and putting next on the left and previous on the right in the entry.html layout. This is still not quite right, though, because the swap in the .rb effectively accomplishes nothing, because I’ve been forced to put next and previous on the wrong sides from each other anyway.

Regardless, from the end user perspective it’s working the way I want it to now, even if the code is counterintuitive. I’ll leave it as and try to be content.


Previous Update Next Update

« Repository Setup Permalinks »