Eleventy: Is it possible to paginate collection data?

Created on 10 Mar 2018  ·  17Comments  ·  Source: 11ty/eleventy

I’ve set up some collections, and have indices which I’d like to paginate over the resulting data. I was expecting to be able to use the following template:

---
layout: layouts/default
title: 'Journal'
pagination:
  data: collections.posts
  size: 8
permalink: '/journal/page/{{ pagination.pageNumber }}.html'
---
{% for item in pagination.items %}
  {% include "item/post" %}
{% endfor %}

I might have misunderstood this feature, but is it possible to use collection data as a basis for pagination?

bug high-priority

Most helpful comment

To answer your second question @paulrobertlloyd, the permalink front matter key can use template syntax (including if statements). I’ve added a test for this in the test suite, but the following will work:

---
pagination:
  data: items
  size: 2
items:
  - item1
  - item2
  - item3
  - item4
permalink: paged/{% if pagination.pageNumber > 0 %}page-{{ pagination.pageNumber }}/{% endif %}index.html
---

hey I am still struggling to make paged paginations. Is there an example repo or an output of what this code does? I tried it but it doesn't do what I thought it would. Thanks!

All 17 comments

Yes, I would expect that to work as well and can confirm that it is not. Lemme have a look.

Running through fixing a couple of pagination things and ran into a design question that I’d like input on if you don’t mind @paulrobertlloyd:

If you add a tag to a paginated template, which would you prefer/expect:

  1. That all different page templates (one for each page) be represented independently in the collection
  2. That only the main pre-paginated template show as one entry in the collection

Looking for opinions!

Short answer: 2.

Longer answer. Currently, I’m using server rewrites so that paginated URLs use query strings, rather than paths, i.e. /journal/?page=2 points to /journal/page/2.html (this is because the content of page 2 will change over time whereas a path suggests content appearing at a location won’t change). So from my point of view, if I were to include a paginated template in a collection, I would only want a reference to the index, and would not be concerned with how many pages it may or may not have. But that’s just me; I can imagine others would have use cases where including pages did sense.

Also, while I’m here (!) permalink: '/journal/page/{{ pagination.pageNumber }}.html' suggests to me that the first page of this index would be available at /journal/page/1.html, is that correct? I’m not sure that’s desirable. What would be more useful, I think, would be the ability to provide a permalink for the index (current functionality), and allow for a separate permalink to be provided for paginated pages. That would mean I could then output the following:

/journal/index.html
/journal/page/2.html

Does that make sense?

To answer your second question @paulrobertlloyd, the permalink front matter key can use template syntax (including if statements). I’ve added a test for this in the test suite, but the following will work:

---
pagination:
  data: items
  size: 2
items:
  - item1
  - item2
  - item3
  - item4
permalink: paged/{% if pagination.pageNumber > 0 %}page-{{ pagination.pageNumber }}/{% endif %}index.html
---

if statements in front matter keys… 😍

@nhoizey I should note that not all front matter keys support template syntax. renderData and permalink are the exceptions.

@zachleat ok, thanks for the clarification.

Alright, the code should be in good shape for this now and will be released with 0.2.16.

Do take note that I don’t think Liquid includes work like this @paulrobertlloyd? I might be wrong but I don’t think item/post will do what you want there.

{% for item in pagination.items %}
  {% include "item/post" %}
{% endfor %}

@zachleat Just tested these latest changes, and it works! Nice. Also, so does {% include "item/post" %}, thanks to your recent change that allowed me to set dynamicPartials: true in setLiquidOptions. Lovely stuff 👍🏻

Hmm well I am suspicious because 0.2.16 is not out yet! 😇

Pointed the 11ty dependency to its GitHub repo.

@paulrobertlloyd oh! Well, nevermind me then 😎

0.2.16 will now be 0.3.0, which shouldn’t have a functional impact to you but just fyi.

To answer your second question @paulrobertlloyd, the permalink front matter key can use template syntax (including if statements). I’ve added a test for this in the test suite, but the following will work:

---
pagination:
  data: items
  size: 2
items:
  - item1
  - item2
  - item3
  - item4
permalink: paged/{% if pagination.pageNumber > 0 %}page-{{ pagination.pageNumber }}/{% endif %}index.html
---

hey I am still struggling to make paged paginations. Is there an example repo or an output of what this code does? I tried it but it doesn't do what I thought it would. Thanks!

I'm trying to use this today and it isn't working. I've got a dynamic collection being setup in .eleventy.js, it's called tagList. I then try to use it here:

---
pagination:
    data: tagList
    size: 1
    alias: tag
permalink: tag/{{ tag | slug }}/index.html
---

And I get: Could not resolve pagination key in template data: tagList

I apologize - I see it is collections.tagList. Would it make sense to document this in the Pagination docs?

And it already is. Sigh. Stupid me not CTRL+F on the page. Sorry for the noise!

Was this page helpful?
0 / 5 - 0 ratings