Pagination with Jekyll and Foundation Sites 6

Posted on September 9, 2018 | Reading time 5 minutes
key points
  • I share some code, to add styled pagination for Jekyll sites based on Foundation Sites 6
  • The code runs on GitHub pages, so you don’t need to build your site locally/run jekyll on CI

Prerequisites

This post assumes, that you already have a site running. It’s also a good idea to run bundle update, to get your dependencies up to date. I will utilize the Jekyll pagination plugin which is available on GitHub pages, so you don’t need to build your site locally.

Important: the plugin only works when your posts are listed on your index.html page, this is a restriction of GitHub pages, which bundles jekyll-paginate in version 1.1.0 at the time of writing.

The glorious pagination control we will create

Configuration

In your _config.yml, add the pagination plugin and configure it, for instance with the code below:

1
2
3
4
5
6
plugins:
  # Other plugins go here
 - jekyll-paginate

paginate: 5
paginate_path: "/posts/page:num/"
_config.yml
  • The entry under plugins simply loads the plugin. If you get any errors when building your page, make sure your gemfile contains gem "github-pages", group: :jekyll_plugins and rerun bundle install
  • paginate sets the number of pages to display on one page
  • paginate_path specifies where the page files will be located. The first page will always be index.html, subsequent files will be in this case /posts/page1/, /posts/page2/, /posts/page3/, and so on.

See the official documentation for more details about these options.

The paginator-element

Create the file _includes/paginator.html. Files in this directory can be included via {% include paginator.html %}, so you don’t need to have the same code twice, if you want to place the controls above and below your posts. The code for this file is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{% if paginator.total_pages > 1 %}
<div class="pagination">
    <nav aria-label="Pagination">
        <ul class="pagination text-center">
        {% if paginator.previous_page %}
        <li class="pagination-previous"><a href="{{ paginator.previous_page_path }}">Previous</a></li>
        {% else %}
        <li class="pagination-previous disabled">Previous</li>
        {% endif %}

        {% for counter in (1..paginator.total_pages) %}
            {% comment %}
                Special case: page1 will be the index page, so the link has to be generated manually
            {% endcomment %}

            {% if counter == 1%}
                {% if counter == paginator.page %}
                <li class="current">{{ counter }}</li>
                {% else %}
                <li><a href="/">{{ counter }}</a></li>
                {% endif %}
            {% else %}
                {% if counter == paginator.page %}
                <li class="current">{{ counter }}</li>
                {% else %}
                <li><a href="/posts/page{{ counter }}">{{ counter }}</a></li>
                {% endif %}
            {% endif %}

        {% endfor %}

        {% if paginator.next_page %}
        <li class="pagination-next"><a href="{{ paginator.next_page_path }}">Next</a></li>
        {% else %}
        <li class="pagination-next disabled">Next</li>
        {% endif %}
        </ul>
    </nav>
</div>
{% endif %}
_includes/paginator.html

This code will create the control only, if there are actually multiple pages. The appropriate CSS classes are applied for the current page, as well as all the other elements. The edge case for the first page, which is just index.html instead of /posts/page1.

Important: Your paginate_path needs to match href="/posts/page{{ counter }}" on line 26.

Adjusting the index.html file

Your index.html has most likely something like the following to display your posts:

1
2
3
{% for post in site.posts %}
    # HTML code to display each post
{ % endfor %}
pseudocode that displays posts without pagination

This needs to be adjusted slightly, and the paginator.html needs to be included:

1
2
3
4
5
{% for post in paginator.posts %}
    # HTML code to display each post
{ % endfor %}

{% include paginator.html %}
display paginated posts

Conclusion

The code in this post is in the public domain (see below), so feel free to reuse it. This pagination control is easy to implement on GitHub pages. If you need more advanced features, there is jekyll-paginate-v2 which is also backwards compatible. The plugin there unfortunately is not supported on GitHub pages, so you’ll need to set up continuous integration, for instance with Travis in order to use it.

If you reuse the code, I’d appreciate a ping back in the comments, but this is not required.

License for the paginate element in this post

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>
license for the pagination element presented here

Comments

comments powered by Disqus