Preface
Goal: Apply Glenn McComb Pagination using Jekyll.
Source Code
This article use tutor-05 theme. We will create it step by step.
1: Source
I respect copyright. The code below copied, and pasted from:
I made a slight modification. But of course the logic remain the same.
I mostly write it down in my blog, because I do not want to forget what I learn. An easier place for me to find the modified version of this good code.
2: Preview: General
It is not easy to explain by words. Let me explain what we want to achive by using these images below. The box without underline, is the active page. since we have 17 articles and 3 page for each pagination, then we have 9 pages of pagination. We have from first page (1), to last page (9).
This is what we want to achieve in this tutorial.
Layout Liquid: Blog
Consider use pagination-v1/03-adjacent.html
partial,
in _layouts/blog.html
.
{% include pagination-v1/03-adjacent.html %}
Animation: Combined Version
This is the complete version. We will achieve this later.
Animation: Stripped Version
I’m following Glenn McComb code, combined with my own code, and this is the result.
Sample: An Example
Consider get one frame, a sample, because we need an example. This is what we want to achieve in this tutorial.
HTML Preview
The HTML that we want to achieve in this article, is similar as below.
<nav role="navigation">
<!-- Page numbers. -->
[ <a href="/pages/blog-3">3</a> ]
[ <a href="/pages/blog-4">4</a> ]
[ 5 ]
[ <a href="/pages/blog-6">6</a> ]
[ <a href="/pages/blog-7">7</a> ]
</nav>
The Riddle
How do we achieve this ?
3: Custom Pagination in Liquid
This would be a long liquid code.
-
First of all, we need to setup flag named
page_current_flag
, to decide which pagination should be shown, and which should be hidden. -
The second step, is to define which variable required to make decision.
-
The third step, is to perform conditional decision.
-
Show pagination based on the flag above.
This utilized page_current_flag
with complex algorithm.
Prepare Variable
Adjacent initialization:
{% capture spaceless %}
{% assign page_current = paginator.page %}
{% assign link_offset = 2 %}
{% assign link_max = link_offset | times: 2 | plus: 1 %}
{% assign limit_lower = link_offset | plus: 1 %}
{% assign limit_upper = total_pages | minus: link_offset %}
{% assign min_lower = link_max %}
{% assign max_upper = total_pages | minus: link_max %}
{% assign lower_offset = page_current | minus: link_offset %}
{% assign upper_offset = page_current | plus: link_offset %}
{% endcapture %}
And, common initialization, before that:
{% capture spaceless %}
{% assign total_pages = paginator.total_pages %}
{% endcapture %}
<nav role="navigation">
{% if total_pages > 1 %}
{% capture spaceless %}
<!-- Get paginate_root from page in frontmatter -->
{% if page.paginate_root == nil %}
{% assign paginate_root = "/" %}
{% else %}
{% assign paginate_root = page.paginate_root %}
{% endif %}
{% assign p_first = paginate_root | prepend: site.baseurl %}
...
{% endcapture %}
...
{% endif %}
</nav>
Calculating Flag Value
The long complex calculation
<!-- Page numbers. -->
{% for page_cursor in (1..total_pages) %}
{% capture spaceless %}
<!-- Flag Calculation -->
{% assign page_current_flag = false %}
{% if total_pages > link_max %}
<!-- Complex page numbers. -->
<!-- Lower limit pages. -->
<!-- If the user is on a page which is in the lower limit. -->
{% if page_current <= limit_lower %}
<!-- If the current loop page is less than max_links. -->
{% if page_cursor <= min_lower %}
{% assign page_current_flag = true %}
{% endif %}
<!-- Upper limit pages. -->
<!-- If the user is on a page which is in the upper limit. -->
{% elsif page_current >= limit_upper %}
<!-- If the current loop page is greater than total pages minus $max_links -->
{% if page_cursor > max_upper %}
{% assign page_current_flag = true %}
{% endif %}
<!-- Middle pages. -->
{% else %}
{% if (page_cursor >= lower_offset) and (page_cursor <= upper_offset) %}
{% assign page_current_flag = true %}
{% endif %}
{% endif %}
{% else %}
<!-- Simple page numbers. -->
{% assign page_current_flag = true %}
{% endif %}
{% endcapture %}
<!-- Show Pager. -->
...
{% endfor %}
I know this is also a looong code. We are going to make this simpler, by using filter plugin in later chapter.
Using Flag Value
<!-- Page numbers. -->
{% for page_cursor in (1..total_pages) %}
{% capture spaceless %}
<!-- Flag Calculation -->
{% assign page_current_flag = false %}
...
{% endcapture %}
<!-- Show Pager. -->
{% if page_current_flag == true %}
{% if page_cursor == page_current %}
[ {{ page_cursor }} ]
{% else %}
{% capture spaceless %}
{% if page_cursor == 1 %}
{% assign p_link = p_first %}
{% else %}
{% assign p_link = site.paginate_path
| relative_url
| replace: ':num', page_cursor %}
{% endif %}
{% endcapture %}
[ <a href="{{ p_link }}">{{ page_cursor }}</a> ]
{% endif %}
{% endif %}
{% endfor %}
Skeleton
To get more understanding about this filter, consider to examine this skeleton below:
{% capture spaceless %}
<!-- Flag Calculation -->
{% assign page_current_flag = false %}
{% if total_pages > link_max %}
<!-- Complex page numbers. -->
<!-- Lower limit pages. -->
{% if page_current <= limit_lower %}
...
<!-- Upper limit pages. -->
{% elsif page_current >= limit_upper %}
...
<!-- Middle pages. -->
{% else %}
...
{% endif %}
{% else %}
<!-- Simple page numbers. -->
{% assign page_current_flag = true %}
{% endif %}
{% endcapture %}
4: Math: Basic Algebra
Assumption
Consider our previous example, a blog post contain seventeen posts. This time with two adjacent. It means, two indicators before selected page, and another two indicators after selected page,
# CONST
Total Post = 17
Per Page = 2
link_offset = 2
# COMPUTED
total_pages = 9
Equation
We should manually, do the math.
EQUATION
max_links = (link_offset * 2) + 1 = 5
lower_limit = 1 + link_offset = 3
upper_limit = 9 - link_offset = 7
The real code is shown as below:
{% capture spaceless %}
{% assign page_current = paginator.page %}
{% assign link_offset = 2 %}
{% assign link_max = link_offset | times: 2 | plus: 1 %}
{% assign limit_lower = link_offset | plus: 1 %}
{% assign limit_upper = total_pages | minus: link_offset %}
{% endcapture %}
Again, that source above are, ported from:
Table
The result is on this table below.
# ALGEBRA
+-------------+-------+-------+-------+-------+-------+
| pagination | 2 | 3 | 5 | 10 | 20 |
+-------------+-------+-------+-------+-------+-------+
| VARIABLE |
| total_pages | 9 | 6 | 4 | 2 | N/A |
| max_links | 5 | 5 | 5 | 5 | N/A |
| lower_limit | 3 | 3 | 3 | 3 | N/A |
| upper_limit | 7 | 4 | 2 | 0 | N/A |
+-------------+-------+-------+-------+-------+-------+
The Same Riddle
How does it works ?
Really! It is confusing.
Luckily, there is explanation for this, for the curious one.
Math in Details
I provide separate article with thorough explanation of the logic, used by this Glenn McComb Pagination.
What is Next ?
Consider continue reading [ Jekyll Plain - Pagination - Logic ].
Thank you for reading.