eleventy
eleventy copied to clipboard
#1036 Add skip parameter to pagination plugin
This PR adds an option to skip the first n items of a pagination. This allows usecases as described in #1036, where one might want to show the first n items on onether page and then paginate over the rest.
fixes #1036
Huh! So this is like a start index?
Yeah right. Basically it's a wrapper around [].slice().
Do we need test(s) for skip + the before callback as well?
Curious if the skip would occur before or after the before callback.
@pdehaan I added only one happy path and one sad path test for skip in this PR.
Also the behavior is described in the docs PR: https://github.com/11ty/11ty-website/pull/1440 Basically it happens last, since it should take effect after reversing and filtering.
Personally I'm unsure about the name 'skip'.
FWIW there's a few other related options pagination could have - start index, end index, count. I've had a few cases where I've wanted to limit or truncate my set of options.
One possible way of supporting all of these could be for a range parameter.
@edwardhorsford Ahh, that might be a good idea. I came from the point of the SQL "SKIP" command. How would you make this range parameter?
My first suggestion would be something like this:
range:
first: 3
last: -4
count: 5
Where negative values mean "from last", where "-1" means the last element similar to Array.at(). Count is considered a max.
- If only first is set, it's like
[].slice(first). - If first and count is set, it's like
[].slice(first, first+count) - If only first and last is set, it's like
[].slice(first, last+1) - If count is set, it's like
[].slice(0, count) - if last is set, it's like
[].slice(last) - if last and count is set, it's like
[].slice(last, last-count) - If all three are set, it's like
[].slice(first, last+1).slice(0, count)
Additionally we could support a string value for range in the form of Rust Ranges, so range: 0..5 or range: 0..=4. Here the first number is read as "first" from above and the second as "last" (for ..= or last-1 for ..).
@Snapstromegon yep, I had a similar thought - using negative numbers to count backwards for the end.
I suspect your first example with an object and properties is easier to read and understand than the Rust ranges.
I might suggest different names though... perhaps:
range:
start: 10
end: -4
limit: 100
I suspect users would be unlikely to want to use both end and limit simultaneously, but seems fine to support both as long as the priority is clear.
I speculate count might be misread as an expectation that number of pages should be generated - when in reality it's either a limit or truncation.
My main use for a limit so far has been where I'm working on a pagination file that outputs many hundreds of pages - but for development I only need a small number to test. My solution so far has been filtering the data with the before callback.
@edwardhorsford limit sounds better. I also think of supporting the range and object syntax at the same time, so it's not one or the other (this is, so the simpler way of start and end can be shorter).
I also think that limit is fairly good semantically coming from SQL, since it clearly transports the priority (first select by start and end, then only take the limit amount).
What I personally disagree with, is that start and end are better names, because first and last clearly state wether or not the selected range is inclusive or not.
E.g. if I have this data:
- zero
- one
- two
- three
- four
- five
- six
- seven
And I'd do
range:
start: 2
end: 4
Would I get ['two', 'three'] or ['two', 'three', 'four']?
(I would keep this similar to [].slice() and make the range non-inclusive.