Skip to content

Commit ca23248

Browse files
committed
add pagination
1 parent daba545 commit ca23248

3 files changed

Lines changed: 242 additions & 163 deletions

File tree

.eleventy.js

Lines changed: 3 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { minify } from "html-minifier";
22

3-
import { createRequire } from "node:module";
4-
import { readFileSync } from "fs";
5-
6-
const require = createRequire(import.meta.url);
7-
const collectionControl = require("./src/_data/collectionsControl.json");
8-
93
// the files we want to use for our collections
10-
let gardenStr = "./src/pages/garden/node/**/*.{md,csv}";
4+
const gardenStr = "./src/pages/garden/node/**/*.{md,csv}";
115

126
import slugify from "./utils/slugify.js";
137

@@ -22,6 +16,7 @@ import {
2216
} from "./conf/components/social/social.js";
2317
import javascript from "./conf/templating/javascript.js";
2418
import filters from "./conf/filters.js";
19+
import { taxes } from "./conf/collections/taxes.js";
2520

2621
Error.stackTraceLimit = 100;
2722

@@ -112,146 +107,7 @@ export default function (eleventyConfig) {
112107
return redirects;
113108
});
114109

115-
eleventyConfig.addCollection("taxes", function (collectionApi) {
116-
// lets make a variable to hold our taxonomies and values
117-
let taxAndValues = [];
118-
// We need to get each post in our posts folder. In my case this is /node
119-
const nodes = collectionApi.getFilteredByGlob(gardenStr);
120-
// next lets iterate over all the nodes
121-
nodes.forEach((node) => {
122-
// and then iterate over the taxonomies
123-
for (const [taxonomy, value] of Object.entries(collectionControl)) {
124-
// I don't want to paginate date, for instance
125-
// this is why my collectionControl is using objects instead of arrays
126-
// @ts-ignore
127-
if (value.excludeFromPagination) continue;
128-
else if (node?.data?.[taxonomy]) {
129-
// this is typeof on drugs
130-
switch (
131-
{}.toString
132-
.call(node.data[taxonomy])
133-
.match(/\s([a-zA-Z]+)/)[1]
134-
.toLowerCase()
135-
) {
136-
// if it is an array (for tags especially)
137-
case "array":
138-
node.data[taxonomy].forEach((item) => {
139-
taxAndValues.push([taxonomy, item]);
140-
});
141-
break;
142-
// otherwise
143-
default:
144-
taxAndValues.push([taxonomy, node.data[taxonomy]]);
145-
}
146-
}
147-
}
148-
});
149-
150-
// custom set, sets don't work with objects
151-
// @ts-ignore
152-
const unique = [...new Set(taxAndValues.map(JSON.stringify))].map(
153-
// @ts-ignore
154-
JSON.parse,
155-
);
156-
157-
return unique;
158-
});
159-
160-
eleventyConfig.addCollection("taxesDiffer", function (collectionApi) {
161-
let taxAndValues = [];
162-
const nodes = collectionApi.getFilteredByGlob(gardenStr);
163-
const differ =
164-
Object.keys(collectionControl)[
165-
Object.values(collectionControl).findIndex(
166-
// @ts-ignore
167-
(value) => value.mode == "differentiator",
168-
)
169-
];
170-
nodes.forEach((node) => {
171-
for (const [taxonomy, value] of Object.entries(collectionControl)) {
172-
// @ts-ignore
173-
if (value.excludeFromPagination) continue;
174-
else if (node?.data?.[taxonomy]) {
175-
switch (
176-
{}.toString
177-
.call(node.data[taxonomy])
178-
.match(/\s([a-zA-Z]+)/)[1]
179-
.toLowerCase()
180-
) {
181-
case "array": {
182-
node.data[taxonomy].forEach((item) => {
183-
if (!(taxonomy == differ && item == node.data[differ]))
184-
taxAndValues.push([taxonomy, item, node.data[differ]]);
185-
});
186-
break;
187-
}
188-
default:
189-
if (
190-
!(
191-
taxonomy == differ && node.data[taxonomy] == node.data[differ]
192-
)
193-
)
194-
taxAndValues.push([
195-
taxonomy,
196-
node.data[taxonomy],
197-
node.data[differ],
198-
]);
199-
}
200-
}
201-
}
202-
});
203-
204-
// custom set, sets don't work with objects
205-
// @ts-ignore
206-
const unique = [...new Set(taxAndValues.map(JSON.stringify))].map(
207-
// @ts-ignore
208-
JSON.parse,
209-
);
210-
211-
return unique;
212-
});
213-
214-
eleventyConfig.addCollection("nestedTax", function (collectionApi) {
215-
let nestedTax = {};
216-
const nodes = collectionApi.getFilteredByGlob(gardenStr);
217-
nodes.forEach((node) => {
218-
for (const [taxonomy, value] of Object.entries(collectionControl)) {
219-
const taxValue = node.data[taxonomy];
220-
221-
// @ts-ignore
222-
if (value.excludeFromPagination) continue;
223-
else if (node?.data?.[taxonomy]) {
224-
if (!nestedTax[taxonomy]) nestedTax[taxonomy] = {};
225-
switch (
226-
{}.toString
227-
.call(taxValue)
228-
.match(/\s([a-zA-Z]+)/)[1]
229-
.toLowerCase()
230-
) {
231-
case "array": {
232-
taxValue.forEach((item) => {
233-
// if the value in the object does not yet exist
234-
if (!nestedTax[taxonomy][item]) nestedTax[taxonomy][item] = [];
235-
// then add the entire page to it
236-
nestedTax[taxonomy][item].push(node);
237-
});
238-
break;
239-
}
240-
// otherwise
241-
default: {
242-
// if the value in the object does not yet exist
243-
if (!nestedTax[taxonomy][taxValue])
244-
nestedTax[taxonomy][taxValue] = [];
245-
// then add the entire page to it
246-
nestedTax[taxonomy][taxValue].push(node);
247-
}
248-
}
249-
}
250-
}
251-
});
252-
253-
return nestedTax;
254-
});
110+
taxes(eleventyConfig);
255111

256112
javascript(eleventyConfig);
257113
scss(eleventyConfig);

conf/collections/taxes.js

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import { createRequire } from "node:module";
2+
const require = createRequire(import.meta.url);
3+
const collectionControl = require("../../src/_data/collectionsControl.json");
4+
const gardenStr = "./src/pages/garden/node/**/*.{md,csv}";
5+
6+
// this is typeof on drugs
7+
function getType(value) {
8+
return {}.toString
9+
.call(value)
10+
.match(/\s([a-zA-Z]+)/)[1]
11+
.toLowerCase();
12+
}
13+
14+
function standard(collectionApi) {
15+
// lets make a variable to hold our taxonomies and values
16+
const taxAndValues = {};
17+
// We need to get each post in our posts folder. In my case this is /node
18+
const nodes = collectionApi.getFilteredByGlob(gardenStr);
19+
// next lets iterate over all the nodes
20+
for (const node of nodes) {
21+
// and then iterate over the taxonomies
22+
for (const [taxonomy, value] of Object.entries(collectionControl)) {
23+
// I don't want to paginate date, for instance
24+
// this is why my collectionControl is using objects instead of arrays
25+
// @ts-expect-error
26+
if (value.excludeFromPagination) continue;
27+
if (node?.data?.[taxonomy]) {
28+
switch (getType(node.data[taxonomy])) {
29+
// if it is an array (for tags especially)
30+
case "array":
31+
for (const item of node.data[taxonomy]) {
32+
if (!taxAndValues[`${taxonomy}/./${item}`])
33+
taxAndValues[`${taxonomy}/./${item}`] = 0;
34+
taxAndValues[`${taxonomy}/./${item}`] += 1;
35+
}
36+
break;
37+
// otherwise
38+
default:
39+
if (!taxAndValues[`${taxonomy}/./${node.data[taxonomy]}`])
40+
taxAndValues[`${taxonomy}/./${node.data[taxonomy]}`] = 0;
41+
taxAndValues[`${taxonomy}/./${node.data[taxonomy]}`] += 1;
42+
}
43+
}
44+
}
45+
}
46+
return taxAndValues;
47+
}
48+
49+
/** @param {import("@11ty/eleventy/UserConfig").default} eleventyConfig */
50+
export function taxes(eleventyConfig) {
51+
// biome-ignore lint/complexity/useArrowFunction: <explanation>
52+
eleventyConfig.addCollection("taxes", function (collectionApi) {
53+
const taxAndValues = standard(collectionApi);
54+
55+
// @ts-ignore
56+
const unique = Object.keys(taxAndValues).map((key) => {
57+
const [taxonomy, value] = key.split("/./");
58+
return [taxonomy, value];
59+
});
60+
61+
return unique;
62+
});
63+
64+
// biome-ignore lint/complexity/useArrowFunction: <explanation>
65+
eleventyConfig.addCollection("taxesPaged", function (collectionApi) {
66+
const taxAndValues = standard(collectionApi);
67+
68+
const paginatedResults = [];
69+
const maxItemsPerPage = 30;
70+
const minItemsForLastPage = 5;
71+
72+
for (const key of Object.keys(taxAndValues)) {
73+
const [taxonomy, value] = key.split("/./");
74+
let totalItems = taxAndValues[key];
75+
let pageNumber = 0;
76+
77+
if (collectionControl[taxonomy].mode !== "differentiator") {
78+
paginatedResults.push({
79+
t: taxonomy,
80+
v: value,
81+
n: pageNumber,
82+
itemsInPage: totalItems,
83+
hasNext: false,
84+
hasPrev: false,
85+
});
86+
continue;
87+
}
88+
89+
while (totalItems > 0) {
90+
let itemsInPage = Math.min(totalItems, maxItemsPerPage);
91+
92+
if (
93+
totalItems - itemsInPage < minItemsForLastPage &&
94+
totalItems > maxItemsPerPage
95+
) {
96+
itemsInPage += totalItems - itemsInPage;
97+
}
98+
99+
paginatedResults.push({
100+
t: taxonomy,
101+
v: value,
102+
n: pageNumber,
103+
itemsInPage: itemsInPage,
104+
hasNext: totalItems > itemsInPage,
105+
hasPrev: pageNumber > 0,
106+
});
107+
108+
totalItems -= itemsInPage;
109+
pageNumber++;
110+
}
111+
}
112+
113+
return paginatedResults;
114+
});
115+
116+
// biome-ignore lint/complexity/useArrowFunction: <explanation>
117+
eleventyConfig.addCollection("taxesDiffer", function (collectionApi) {
118+
const taxAndValues = [];
119+
const nodes = collectionApi.getFilteredByGlob(gardenStr);
120+
const differ =
121+
Object.keys(collectionControl)[
122+
Object.values(collectionControl).findIndex(
123+
// @ts-expect-error
124+
(value) => value.mode === "differentiator",
125+
)
126+
];
127+
for (const node of nodes) {
128+
for (const [taxonomy, value] of Object.entries(collectionControl)) {
129+
// @ts-ignore
130+
if (value.excludeFromPagination) continue;
131+
if (node?.data?.[taxonomy]) {
132+
switch (getType(node.data[taxonomy])) {
133+
case "array": {
134+
for (const item of node.data[taxonomy]) {
135+
if (!(taxonomy == differ && item == node.data[differ]))
136+
taxAndValues.push([taxonomy, item, node.data[differ]]);
137+
}
138+
break;
139+
}
140+
default:
141+
if (
142+
!(
143+
taxonomy == differ && node.data[taxonomy] == node.data[differ]
144+
)
145+
)
146+
taxAndValues.push([
147+
taxonomy,
148+
node.data[taxonomy],
149+
node.data[differ],
150+
]);
151+
}
152+
}
153+
}
154+
}
155+
156+
// custom set, sets don't work with objects
157+
// @ts-ignore
158+
const unique = [...new Set(taxAndValues.map(JSON.stringify))].map(
159+
// @ts-ignore
160+
JSON.parse,
161+
);
162+
163+
return unique;
164+
});
165+
166+
// biome-ignore lint/complexity/useArrowFunction: <explanation>
167+
eleventyConfig.addCollection("nestedTax", function (collectionApi) {
168+
const nestedTax = {};
169+
const nodes = collectionApi.getFilteredByGlob(gardenStr);
170+
for (const node of nodes) {
171+
for (const [taxonomy, value] of Object.entries(collectionControl)) {
172+
const taxValue = node.data[taxonomy];
173+
174+
// @ts-expect-error
175+
if (value.excludeFromPagination) continue;
176+
if (node?.data?.[taxonomy]) {
177+
if (!nestedTax[taxonomy]) nestedTax[taxonomy] = {};
178+
switch (getType(taxValue)) {
179+
case "array": {
180+
for (const item of taxValue) {
181+
// if the value in the object does not yet exist
182+
if (!nestedTax[taxonomy][item]) nestedTax[taxonomy][item] = [];
183+
// then add the entire page to it
184+
nestedTax[taxonomy][item].push(node);
185+
}
186+
break;
187+
}
188+
// otherwise
189+
default: {
190+
// if the value in the object does not yet exist
191+
if (!nestedTax[taxonomy][taxValue])
192+
nestedTax[taxonomy][taxValue] = [];
193+
// then add the entire page to it
194+
nestedTax[taxonomy][taxValue].push(node);
195+
}
196+
}
197+
}
198+
}
199+
}
200+
201+
return nestedTax;
202+
});
203+
}

0 commit comments

Comments
 (0)