Pagination for Jekyll pages.
You can paginate one or more collections, on a per-page basis, by defining a paginate
object in template front-matter.
In the following example, the articles
collection will be reduced to multiple pages containing 8
or fewer document instances:
---
...
paginate:
articles:
per: 8
---
The pages will be generated dynamically according to the name of the template. For example, if the file described in the example above was named articles.html
the paths for the generated pages would resolve to /articles/page/2/index.html
, /articles/page/3/index.html
, etc.
The paginated collections are exposed to the template via a docs
collection on the page.articles
object:
{% for doc in page.articles.docs %}
...
{% endfor %}
In addition, there are several other data attributes attached to the page to help you build out pagination navigation, including:
total_pages
: Total number of pagination pages.page
: Current page number.previous_page
: Previous page number.next_page
: Next page number.
The first n
items can be extracted from the paginated collection by defining an offset
number. This is helpful for exposing a certain number of featured docs on the landing page of your collection. For example:
---
...
paginate:
articles:
offset: 3
per: 8
---
This would result in the first three items being attached to an offset
array on the page.articles
object:
{{ page.articles.offset }}
And the remaining items would continue paginating as normal:
{{ page.articles.docs }}
Collections can be filtered (i.e. a subset of the Jekyll collection) by adding a series of where
arguments.
This works by using the where
option within the pagination config and providing a series of key-value pairs where the key is the name of the attribute within the collection objects and the value is what that attribute must equal (or contain, more on that below).
For example, to only show articles where the title of the article is "My Title":
---
...
paginate:
articles:
per: 8
where:
title: "My Title"
---
The paginator accepts more than one filter argument, but it will treat the filters as AND conditions, meaning both conditions must be true for the document to be presented in the collection.
---
...
paginate:
articles:
per: 8
where:
title: "My Title"
subtitle: "My Subtitle"
---
Filtering also supports dynamic values. Inspired by ruby symbols, any value with a leading colon will look for that value in the data object of the page that is rendering the collection. For example:
---
...
title: "Hello World"
paginate:
articles:
per: 8
where:
subtitle: :title
---
In that example, the only articles that would be returned in the collection would be those where their subtitle matched the title of the page rendering the collection (i.e. "Hello World").
Filtering also supports array fields and looks for only a single match. The paginator does this automatically. Let's say articles have tags via a tags
field. And the current tag is the title of the page rendering the collection:
---
...
paginate:
articles:
per: 8
where:
tags: :title
---
In this case, only those articles containing at least one tag matching the title of the page rendering the collection would be returned.
If the attribute to filter is an object (Hash) or an array of objects, use a period to chain together attributes, enabling the paginator to dig into the objects and match the correct value. Using the example above, suppose tags
was an array of objects each containing a title
key. To extract the correct value, the config would look like this:
---
...
paginate:
articles:
per: 8
where:
tags.title: :title
---
The paginator takes the collection as presented by Jekyll, but that can be overridden using the sort
. The sort
option takes two arguments, separated by a space. The first argument is the method by which to sort and the second is the sorting direction (asc
/desc
). The direction is optional and is asc
by default.
For example, to sort articles in reverse chronological order, you could do something like this:
---
...
paginate:
articles:
per: 8
sort: date desc
---
But sorting articles by title could look like this:
---
...
paginate:
articles:
per: 8
sort: title
---
You can limit the first n
pages from your paginated collection by defining a limit
number. This is helpful if you'd like to show the first n
pages without generating pages for the entire collection.
For example, to show the first 8 most recent articles and no additional pages:
---
...
paginate:
articles:
per: 8
limit: 1
---
The paginator will merge collections in the event you are combining multiple collections into a single array. This is done via the collections
option, which takes an array of collection names:
---
...
paginate:
my_collection:
collections:
- articles
- videos
per: 8
---
In this case the name of the collection (my_collection
) can be value and is still the method by which we access the docs:
{{ page.my_collection.docs }}
Sorting and filtering still apply to merged collections, assuming the data field exists on each doc within all applicable collections.
This project is licensed under the 3-Clause BSD License.