Paginate the patches page

Fri Mar 14 2025

tucker.mcknight@gmail.com

Pagination has to be done manually, since we are trying
to create URLs that have two "vaiable" values in them:
the first is the repo name, and the second is the page
number.

Eleventy can iterate on one value, creating pages automatically
on just one of those variables. So we need to create the
chunks of patches manually as a "page object", then use eleventy's
pagination feature to iterate over each one of those (so, a page
size of 1, each page object getting its own page).  

The page object has information about the repo name and which
page number it should be on, so those can be put in the URL
in the permalink field.

I ended up asking about this on eleventy's github discussions:
https://github.com/11ty/eleventy/discussions/3681
  addfile ./_data/paginatedPatches.js

a9511ba4be26f5187c48a5abebf340ad377d41c7

darcs pull https://repos.tuckerm.us/repos/eleventy-darcs/branches/main -h a9511ba4be26f5187c48a5abebf340ad377d41c7
_data/paginatedPatches.js:1
Before
After
import flatPatchesFunc from './flatPatches.js'

export default async () => {
  const flatPatches = await flatPatchesFunc()

  let paginatedPatches = []
  const patchesPerPage = 5

  flatPatches.forEach((patch) => {
    const index = paginatedPatches.findIndex((page) => {
      return page.repoName === patch.repoName && page.patches.length <= patchesPerPage
    })

    if (index === -1) {
      const pageNumber = paginatedPatches.filter(page => page.repoName === patch.repoName).length + 1
      paginatedPatches.push({
        repoName: patch.repoName,
        patches: [patch.patch],
        // current page number is one more than "how many items in paginatedPatches already
        // have repoName as their repo name.
        pageNumber,
      })
    }
    else {
      paginatedPatches[index].patches.push(patch.patch)
    }
  })

  return paginatedPatches
}
eleventy.config.js:23
Before
After
  eleventyConfig.addFilter("pagesJustForRepo", (pages, repoName) => {
    return pages.filter(page => page.repoName === repoName)
  })
main.css:56
Before
After
.patch-pages {
  list-style: none;
  overflow: hidden;
}
.patch-pages li {
  float: left;
  margin: 0.25rem;
}
.patch-pages li:first-of-type {
  margin-left: 0;
}
.page-current {
  font-weight: bold;
}
patches.njk:3
Before
  data: repos
After
  data: paginatedPatches
patches.njk:5
Before
  alias: repo
permalink: "repos/{{repo | slugify}}/patches/"
After
  alias: patchPage
permalink: "repos/{{patchPage.repoName | slugify}}/patches/page{{patchPage.pageNumber}}/"
patches.njk:8
Before
<h2><a href="/repos/{{repo | slugify}}">{{repo}}</a></h2>
<h3>Patches</h3>
After
<h2><a href="/repos/{{patchPage.repoName | slugify}}">{{patchPage.repoName}}</a></h2>
<h3>Patches, page {{patchPage.pageNumber}}</h3>
<ul class="patch-pages">
{% for pageObj in (paginatedPatches | pagesJustForRepo(patchPage.repoName)) %}
  <li>
    <a {% if pageObj.pageNumber == patchPage.pageNumber %}class="page-current" {% endif %}href="/repos/{{patchPage.repoName | slugify}}/patches/page{{pageObj.pageNumber}}">Page {{ pageObj.pageNumber }}</a>
  </li>
{% endfor %}
</ul>
patches.njk:19
Before
  {% for patch in repos[repo].patches %}
After
  {% for patch in patchPage.patches %}
patches.njk:22
Before
        <span class="patch-name"><a href="/repos/{{repo | slugify}}/patches/{{patch.hash}}">{{patch.name}}</a></span>
After
        <span class="patch-name"><a href="/repos/{{patchPage.repoName | slugify}}/patches/{{patch.hash}}">{{patch.name}}</a></span>
patches.njk:29
Before
After
</ul>

<ul class="patch-pages">
{% for pageObj in (paginatedPatches | pagesJustForRepo(patchPage.repoName)) %}
  <li>
    <a {% if pageObj.pageNumber == patchPage.pageNumber %}class="page-current" {% endif %}href="/repos/{{patchPage.repoName | slugify}}/patches/page{{pageObj.pageNumber}}">Page {{ pageObj.pageNumber }}</a>
  </li>
{% endfor %}
repo.njk:11
Before
  <li><a href="/repos/{{repo | slugify}}/patches">Patches</a></li>
After
  <li><a href="/repos/{{repo | slugify}}/patches/page1">Patches</a></li>