From b1b44d00f63aff564facab3c79853df7d4ebe232 Mon Sep 17 00:00:00 2001 From: Gil Date: Mon, 19 May 2025 13:23:33 -0500 Subject: [PATCH] Paginate categories and tags --- .eleventy.js | 135 +++++++++++++++++++++++++++++++- package-lock.json | 7 ++ package.json | 1 + scss/_theme.scss | 5 +- src/404.md | 6 +- src/_includes/nav.njk | 6 +- src/about.md | 38 +++------ src/assets/css/main.css | 5 +- src/assets/css/main.css.map | 2 +- src/categories.njk | 15 ++++ src/changelog.md | 4 +- src/colophon.md | 18 +++++ src/feeds.md | 2 +- src/journal/2025/free-flow-1.md | 2 - src/journal/categories.njk | 19 ----- src/journal/index.md | 2 + src/journal/journal.json | 2 +- src/tags.njk | 15 ++++ 18 files changed, 218 insertions(+), 66 deletions(-) create mode 100644 src/categories.njk create mode 100644 src/colophon.md delete mode 100644 src/journal/categories.njk create mode 100644 src/tags.njk diff --git a/.eleventy.js b/.eleventy.js index d8ffdc8..d2b1bfd 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,9 +1,12 @@ import { RenderPlugin, IdAttributePlugin } from "@11ty/eleventy"; import eleventyNavigationPlugin from "@11ty/eleventy-navigation"; import { feedPlugin } from "@11ty/eleventy-plugin-rss"; + import markdownIt from "markdown-it"; import markdownItFootnote from "markdown-it-footnote"; + import { DateTime } from "luxon"; +import { chunk } from "lodash-es"; export default function (eleventyConfig) { const MARKDOWN_OPTIONS = { @@ -83,7 +86,7 @@ export default function (eleventyConfig) { eleventyConfig.setFrontMatterParsingOptions({ excerpt: true }); // COLLECTIONS - ////// Journal categories + ////// Categories eleventyConfig.addCollection("categories", function (collectionApi) { let categories = new Set(); let posts = collectionApi.getFilteredByTag("post"); @@ -95,11 +98,137 @@ export default function (eleventyConfig) { return Array.from(categories); }); + ////// Paginated tags (by @zachleat) + // See: https://github.com/11ty/eleventy/issues/332#issuecomment-445236776 + // note that this uses the lodash.chunk method, so you’ll have to require that + eleventyConfig.addCollection("tagPagination", function (collectionApi) { + // Get unique list of tags + let tagSet = new Set(); + collectionApi.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 = collectionApi.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, + pageNumber: pageNumber, + pageSize: pagedItems.length, + pageData: pagedItems[pageNumber], + }); + } + } + + /* return data looks like: + [{ + tagName: "tag1", + pageNumber: 0 + pageData: [] // array of items + },{ + tagName: "tag1", + pageNumber: 1 + pageData: [] // array of items + },{ + tagName: "tag1", + pageNumber: 2 + pageData: [] // array of items + },{ + tagName: "tag2", + pageNumber: 0 + pageData: [] // array of items + }] + */ + //console.log( tagMap ); + return tagMap; + }); + + ////// Paginated categories (by @zachleat) + eleventyConfig.addCollection("catPagination", function (collectionApi) { + // Get unique list of tags + let catSet = new Set(); + collectionApi.getAllSorted().map(function (item) { + if ("categories" in item.data) { + let cats = item.data.categories; + + // optionally filter things out before you iterate over? + for (let cat of cats) { + catSet.add(cat); + } + } + }); + + // Get each item that matches the tag + let paginationSize = 10; + let catMap = []; + let catArray = [...catSet]; + for (let catName of catArray) { + let catItems = collectionApi.getAllSorted().filter(function (item) { + if ("categories" in item.data) { + return item.data.categories.includes(catName); + } else { + return false; + } + }); + let pagedItems = chunk(catItems, paginationSize); + //console.log( tagName, tagItems.length, pagedItems.length ); + for ( + let pageNumber = 0, max = pagedItems.length; + pageNumber < max; + pageNumber++ + ) { + catMap.push({ + catName: catName, + pageNumber: pageNumber, + pageSize: pagedItems.length, + pageData: pagedItems[pageNumber], + }); + } + } + + /* return data looks like: + [{ + tagName: "tag1", + pageNumber: 0 + pageData: [] // array of items + },{ + tagName: "tag1", + pageNumber: 1 + pageData: [] // array of items + },{ + tagName: "tag1", + pageNumber: 2 + pageData: [] // array of items + },{ + tagName: "tag2", + pageNumber: 0 + pageData: [] // array of items + }] + */ + //console.log( tagMap ); + return catMap; + }); + return { dir: { input: "src", - includes: "_includes", - layouts: "_layouts", }, }; } diff --git a/package-lock.json b/package-lock.json index a835cb1..f396549 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@11ty/eleventy-navigation": "^1.0.4", "@11ty/eleventy-plugin-rss": "^2.0.4", + "lodash-es": "^4.17.21", "luxon": "^3.6.1", "markdown-it": "^14.1.0", "markdown-it-footnote": "^4.0.0", @@ -2549,6 +2550,12 @@ "node": ">=4" } }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/luxon": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", diff --git a/package.json b/package.json index ef10f39..f201e33 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@11ty/eleventy-navigation": "^1.0.4", "@11ty/eleventy-plugin-rss": "^2.0.4", + "lodash-es": "^4.17.21", "luxon": "^3.6.1", "markdown-it": "^14.1.0", "markdown-it-footnote": "^4.0.0", diff --git a/scss/_theme.scss b/scss/_theme.scss index d7258d0..9d8872e 100644 --- a/scss/_theme.scss +++ b/scss/_theme.scss @@ -38,6 +38,7 @@ $font-mono: "Hack", monospace; --font-sans: #{$font-sans}; --font-disp: #{$font-disp}; --font-mono: #{$font-mono}; + --border-radius: 15px; } /* @@ -134,7 +135,7 @@ hr { #{$green} 99% ); border: solid var(--color-bg-2) 2px; - border-radius: 15px; + border-radius: var(--border-radius); &__header { padding: 15px; border-radius: inherit; @@ -173,7 +174,7 @@ hr { } .box { - border-radius: 15px; + border-radius: var(--border-radius); border: dashed 1px var(--color-ui); background-color: var(--color-bg-2); } diff --git a/src/404.md b/src/404.md index 861d7df..35c011e 100644 --- a/src/404.md +++ b/src/404.md @@ -4,8 +4,6 @@ layout: single permalink: "404.html" --- -# Error 404 +# Error 404: Not found -Uh-oh! Couldn't find that URL on this server. Maybe you had a typo? - -[Go home](/) +Couldn't find the page requested. Check the URL for typos or [go home](/). diff --git a/src/_includes/nav.njk b/src/_includes/nav.njk index b7ec1e5..e1b0753 100644 --- a/src/_includes/nav.njk +++ b/src/_includes/nav.njk @@ -1,9 +1,9 @@ {% set navPages = collections.all | eleventyNavigation %} -