Skip to content

Instantly share code, notes, and snippets.

@MWDelaney
Last active April 21, 2024 08:49
Show Gist options
  • Save MWDelaney/6dd60be5e4c223217d597983d20bde20 to your computer and use it in GitHub Desktop.
Save MWDelaney/6dd60be5e4c223217d597983d20bde20 to your computer and use it in GitHub Desktop.
Tag-friendly pagination for Eleventy
...
postsByTag: function (eleventyConfig) {
let _ = require("lodash");
eleventyConfig.addCollection("postsByTag", function(collection) {
// Get unique list of tags
let tagSet = new Set();
collection.getAllSorted().map(function(item) {
if( "tags" in item.data ) {
let tags = item.data.tags;
// optionally filter things out before you iterate over?
for (let tag of tags) {
tagSet.add(tag);
}
}
});
// Get each item that matches the tag
let paginationSize = 10;
let tagMap = [];
let tagArray = [...tagSet];
for(let tagName of tagArray) {
let tagItems = collection.getFilteredByTag(tagName);
let pagedItems = _.chunk(tagItems, paginationSize);
// console.log( tagName, tagItems.length, pagedItems.length );
for( let pageNumber = 0, max = pagedItems.length; pageNumber < max; pageNumber++) {
tagMap.push({
tagName: tagName,
totalPages: (max - 1),
pageNumber: pageNumber,
pageData: pagedItems[pageNumber]
});
}
}
return tagMap;
});
}
...
---
layout: base.njk
permalink: /blog/{{ tag.tagName | slugify }}/{% if tag.pageNumber > 0 %}/page/{{ tag.pageNumber + 1 }}{% endif %}/index.html
pagination:
data: collections.postsByTag
size: 1
alias: tag
eleventyComputed:
title: "{{ tag.tagName }} Blog {% if tag.pageNumber > 0 %}(Page {{ tag.pageNumber + 1 }}) {% endif %}"
---
{% for post in tag.pageData %}
{% include "partials/blog-item.njk" %}
{% endfor %}
{% include "partials/pagination.njk" %}
<ul class="pages">
{# loop through pages to retrieve index of "current" page, save its value as currentPageIndex so we can reference it later #}
{% set currentPageIndex = '' %}
{# if tag is set, we're in a tag page #}
{% if tag %}
{# tags are easy, we know the current page index already #}
{% set currentPageIndex = tag.pageNumber %}
{% set totalPages = tag.totalPages %}
{% else %}
{# otherwise, we need to loop through all pages to find the current page #}
{% for i in pagination.pages %}
{# if the current page URL matches the URL of the current loop item #}
{% if page.url == pagination.hrefs[ loop.index0 ] %}
{# Set the currentPageIndex to the index of the current loop item so that we can anticipate it and highlight it later #}
{% set currentPageIndex = loop.index0 %}
{% endif %}
{% endfor %}
{% set totalPages = pagination.hrefs.length %}
{% endif %}
{% for pageOfEntries in pagination.pages %}
{# Number of pages to highlight on either side of the current page #}
{% set highlightedRange = 3 %}
{# if the current looped item is the page we're looking at #}
{% if currentPageIndex == loop.index0 %}
{% set currentPage = true %}
{% else %}
{% set currentPage = false %}
{% endif %}
{# if the current looped item is within the highlighted range, or is the current page #}
{% if loop.index0 <= currentPageIndex + highlightedRange and loop.index0 >= currentPageIndex - highlightedRange %}
{% set highlighted = true %}
{% else %}
{% set highlighted = false %}
{% endif %}
{% if loop.index0 <= totalPages %}
{# finally print some HTML #}
<li class="{% if currentPage %}current-page{% endif %} {% if highlighted == true %}highlighted{% endif %}"><a href="{{ pagination.hrefs[ loop.index0 ] }}"{% if page.url == pagination.hrefs[ loop.index0 ] %} aria-current="page"{% endif %}><span class="sr-only">Page </span>{{ loop.index }}</a></li>
{% endif %}
{% endfor %}
</ul>
<nav id="pagination-navigation" class="pagination" aria-labelledby="pagination-navigation">
<h2>Page navigation</h2>
<ol>
{% if tag %}
{% if tag.pageNumber != 0 %}
{% set showPrevious = true %}
{% else %}
{% set showPrevious = false %}
{% endif %}
{% if tag.pageNumber != tag.totalPages %}
{% set showNext = true %}
{% else %}
{% set showNext = false %}
{% endif %}
{% else %}
{% if pagination.href.previous %}
{% set showPrevious = true %}
{% else %}
{% set showPrevious = false %}
{% endif %}
{% if pagination.href.next %}
{% set showNext = true %}
{% else %}
{% set showNext = false %}
{% endif %}
{% endif %}
<li class="previous">{% if showPrevious %}<a href="{{ pagination.href.previous }}">Previous</a>{% else %}Previous{% endif %}</li>
<li>
{% include "partials/pagination-pages.njk" %}
</li>
<li class="next">{% if showNext %}<a href="{{ pagination.href.next }}">Next</a>{% else %}Next{% endif %}</li>
</ol>
</nav>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment