Skip to content

Commit 37ef0f6

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 86c25f6 commit 37ef0f6

File tree

6 files changed

+60
-13
lines changed

6 files changed

+60
-13
lines changed

src/Plugins/Pagination.js

+11-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const lodashSet = require("lodash/set");
44
const EleventyBaseError = require("../EleventyBaseError");
55
const { DeepCopy } = require("../Util/Merge");
66
const { ProxyWrap } = require("../Util/ProxyWrap");
7+
const getPaginationDataKey = require("../Util/GetPaginationDataKey");
78

89
class PaginationConfigError extends EleventyBaseError {}
910
class PaginationError extends EleventyBaseError {}
@@ -32,13 +33,13 @@ class Pagination {
3233
return Pagination.hasPagination(this.data);
3334
}
3435

35-
circularReferenceCheck(data) {
36-
if (data.eleventyExcludeFromCollections) {
36+
circularReferenceCheck() {
37+
if (this.data.eleventyExcludeFromCollections) {
3738
return;
3839
}
3940

40-
let key = data.pagination.data;
41-
let tags = data.tags || [];
41+
let key = getPaginationDataKey(this.data);
42+
let tags = this.data.tags || [];
4243
for (let tag of tags) {
4344
if (`collections.${tag}` === key) {
4445
throw new PaginationError(
@@ -65,7 +66,7 @@ class Pagination {
6566
} else if (!("size" in data.pagination)) {
6667
throw new Error("Missing pagination size in front matter data.");
6768
}
68-
this.circularReferenceCheck(data);
69+
this.circularReferenceCheck();
6970

7071
this.size = data.pagination.size;
7172
this.alias = data.pagination.alias;
@@ -141,16 +142,18 @@ class Pagination {
141142

142143
_has(target, key) {
143144
let notFoundValue = "__NOT_FOUND_ERROR__";
144-
let data = lodashGet(target, key, notFoundValue);
145+
let paginationDataKey = getPaginationDataKey(this.data);
146+
let data = lodashGet(target, paginationDataKey, notFoundValue);
145147
return data !== notFoundValue;
146148
}
147149

148150
_get(target, key) {
149151
let notFoundValue = "__NOT_FOUND_ERROR__";
150-
let data = lodashGet(target, key, notFoundValue);
152+
let paginationDataKey = getPaginationDataKey(this.data);
153+
let data = lodashGet(target, paginationDataKey, notFoundValue);
151154
if (data === notFoundValue) {
152155
throw new Error(
153-
`Could not find pagination data, went looking for: ${key}`
156+
`Could not find pagination data, went looking for: ${paginationDataKey}`
154157
);
155158
}
156159
return data;

src/TemplateMap.js

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

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

@@ -81,16 +82,14 @@ class TemplateMap {
8182
*/
8283
isPaginationOverAllCollections(entry) {
8384
if (entry.data.pagination && entry.data.pagination.data) {
84-
return (
85-
entry.data.pagination.data === "collections" ||
86-
entry.data.pagination.data === "collections.all"
87-
);
85+
const key = getPaginationDataKey(entry.data);
86+
return key === "collections" || key === "collections.all";
8887
}
8988
}
9089

9190
getPaginationTagTarget(entry) {
9291
if (entry.data.pagination && entry.data.pagination.data) {
93-
return this.getTagTarget(entry.data.pagination.data);
92+
return this.getTagTarget(getPaginationDataKey(entry.data));
9493
}
9594
}
9695

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
@@ -706,6 +706,20 @@ test("Pagination `before` Callback with a Filter", async (t) => {
706706
t.deepEqual(templates[0].data.myalias, "item2");
707707
});
708708

709+
test("Pagination when `data` is a function", async (t) => {
710+
let tmpl = getNewTemplate(
711+
"./test/stubs/paged/paged-data-key-func.njk",
712+
"./test/stubs/",
713+
"./dist"
714+
);
715+
716+
let data = await tmpl.getData();
717+
let templates = await tmpl.getTemplates(data);
718+
t.is(templates.length, 2);
719+
t.deepEqual(templates[0].data.pagination.items, ["foo"]);
720+
t.deepEqual(templates[1].data.pagination.items, ["woo"]);
721+
});
722+
709723
test("Pagination `before` Callback with `reverse: true` (test order of operations)", async (t) => {
710724
let tmpl = getNewTemplate(
711725
"./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)