Skip to content

Commit 313c7fa

Browse files
committed
Pagination: let data key be a function
So that pagination data key can be determined dynamically, based on a callback function that gets passed all template data. So you can do something like: ---js { pagination: { data: (data) => { return "collections." + data.foo; }, ...
1 parent 92417d3 commit 313c7fa

6 files changed

+61
-14
lines changed

src/Plugins/Pagination.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const lodashChunk = require("lodash/chunk");
22
const lodashGet = require("lodash/get");
33
const lodashSet = require("lodash/set");
44
const EleventyBaseError = require("../EleventyBaseError");
5+
const getPaginationDataKey = require("../Util/GetPaginationDataKey");
56

67
class PaginationConfigError extends EleventyBaseError {}
78
class PaginationError extends EleventyBaseError {}
@@ -30,13 +31,13 @@ class Pagination {
3031
return Pagination.hasPagination(this.data);
3132
}
3233

33-
circularReferenceCheck(data) {
34-
if (data.eleventyExcludeFromCollections) {
34+
circularReferenceCheck() {
35+
if (this.data.eleventyExcludeFromCollections) {
3536
return;
3637
}
3738

38-
let key = data.pagination.data;
39-
let tags = data.tags || [];
39+
let key = getPaginationDataKey(this.data);
40+
let tags = this.data.tags || [];
4041
for (let tag of tags) {
4142
if (`collections.${tag}` === key) {
4243
throw new PaginationError(
@@ -63,7 +64,7 @@ class Pagination {
6364
} else if (!("size" in data.pagination)) {
6465
throw new Error("Missing pagination size in front matter data.");
6566
}
66-
this.circularReferenceCheck(data);
67+
this.circularReferenceCheck();
6768

6869
this.size = data.pagination.size;
6970
this.alias = data.pagination.alias;
@@ -129,16 +130,18 @@ class Pagination {
129130

130131
_has(target, key) {
131132
let notFoundValue = "__NOT_FOUND_ERROR__";
132-
let data = lodashGet(target, key, notFoundValue);
133+
let paginationDataKey = getPaginationDataKey(this.data);
134+
let data = lodashGet(target, paginationDataKey, notFoundValue);
133135
return data !== notFoundValue;
134136
}
135137

136138
_get(target, key) {
137139
let notFoundValue = "__NOT_FOUND_ERROR__";
138-
let data = lodashGet(target, key, notFoundValue);
140+
let paginationDataKey = getPaginationDataKey(this.data);
141+
let data = lodashGet(target, paginationDataKey, notFoundValue);
139142
if (data === notFoundValue) {
140143
throw new Error(
141-
`Could not find pagination data, went looking for: ${key}`
144+
`Could not find pagination data, went looking for: ${paginationDataKey}`
142145
);
143146
}
144147
return data;
@@ -205,7 +208,7 @@ class Pagination {
205208
getOverrideData(pageItems) {
206209
let override = {
207210
pagination: {
208-
data: this.data.pagination.data,
211+
data: getPaginationDataKey(this.data),
209212
size: this.data.pagination.size,
210213
alias: this.alias,
211214
items: pageItems,

src/TemplateMap.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const EleventyErrorUtil = require("./EleventyErrorUtil");
55
const UsingCircularTemplateContentReferenceError = require("./Errors/UsingCircularTemplateContentReferenceError");
66
const debug = require("debug")("Eleventy:TemplateMap");
77
const debugDev = require("debug")("Dev:Eleventy:TemplateMap");
8+
const getPaginationDataKey = require("./Util/GetPaginationDataKey");
89

910
const EleventyBaseError = require("./EleventyBaseError");
1011

@@ -78,16 +79,14 @@ class TemplateMap {
7879
*/
7980
isPaginationOverAllCollections(entry) {
8081
if (entry.data.pagination && entry.data.pagination.data) {
81-
return (
82-
entry.data.pagination.data === "collections" ||
83-
entry.data.pagination.data === "collections.all"
84-
);
82+
const key = getPaginationDataKey(entry.data);
83+
return key === "collections" || key === "collections.all";
8584
}
8685
}
8786

8887
getPaginationTagTarget(entry) {
8988
if (entry.data.pagination && entry.data.pagination.data) {
90-
return this.getTagTarget(entry.data.pagination.data);
89+
return this.getTagTarget(getPaginationDataKey(entry.data));
9190
}
9291
}
9392

src/Util/GetPaginationDataKey.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const lodashIsFunction = require("lodash/isFunction");
2+
3+
module.exports = function (data) {
4+
return lodashIsFunction(data.pagination.data)
5+
? data.pagination.data(data)
6+
: data.pagination.data;
7+
};

test/GetPaginationDataKeyTest.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const test = require("ava");
2+
const getPaginationDataKey = require("../src/Util/GetPaginationDataKey");
3+
4+
test("getPaginationDataKey when key is string", (t) => {
5+
t.is(getPaginationDataKey({pagination: {data: "foo"}}), "foo");
6+
});
7+
8+
test("getPaginationDataKey when key is function", (t) => {
9+
t.is(
10+
getPaginationDataKey({foo: "bar", pagination: {data: (data) => data.foo}}),
11+
"bar"
12+
);
13+
});

test/PaginationTest.js

+14
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,20 @@ test("Pagination `before` Callback with a Filter", async (t) => {
654654
t.deepEqual(templates[0].data.myalias, "item2");
655655
});
656656

657+
test("Pagination when `data` is a function", async (t) => {
658+
let tmpl = getNewTemplate(
659+
"./test/stubs/paged/paged-data-key-func.njk",
660+
"./test/stubs/",
661+
"./dist"
662+
);
663+
664+
let data = await tmpl.getData();
665+
let templates = await tmpl.getTemplates(data);
666+
t.is(templates.length, 2);
667+
t.deepEqual(templates[0].data.pagination.items, ["foo"]);
668+
t.deepEqual(templates[1].data.pagination.items, ["woo"]);
669+
});
670+
657671
test("Pagination `before` Callback with `reverse: true` (test order of operations)", async (t) => {
658672
let tmpl = getNewTemplate(
659673
"./test/stubs/paged/paged-before-and-reverse.njk",
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---js
2+
{
3+
dataCanBeFoundIn: "items",
4+
pagination: {
5+
data: (data) => data.dataCanBeFoundIn,
6+
size: 1
7+
},
8+
items: ["foo", "woo"]
9+
}
10+
---
11+
<ol>{% for item in pagination.items %}<li>{{ item }}</li>{% endfor %}</ol>

0 commit comments

Comments
 (0)