Preface
Goal: Pagination using Number.
Preview
This is what we want to achieve in this tutorial.
More Recent Code
I have made a better code with Bulma
utilizing site.pagination.permalink
which you can examine at:
1: Prepare
Artefact that we need.
Includes: Pagination: Number
Create an empty artefact. Source code used in this tutorial, is available at this repository:
- /_includes/pagination/02-number.html
Pages: Blog List
Set this blog list page:
- /pages/index.html : github.com/…/pages/index.html.
{% include pagination/02-number.html %}
2: Skeleton
The Structure
Our number pagination contain three parts:
-
Previous Page.
-
Indicator Number.
-
Next Page.
We have already had, this First, and Last, in number. So we do not require it.
HTML Preview
The HTML that we want to achieve in this article, is similar as below.
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<!-- Previous Page. -->
<li class="page-item blog_previous">
<a class="page-link" href="/demo-jekyll/pages/blog-4" rel="prev">«</a>
</li>
<!-- Page numbers. -->
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages">1</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-2">2</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-3">3</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-4">4</a>
</li>
<li class="page-item active">
<span class="page-link">5</span>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-6">6</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-7">7</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-8">8</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-9">9</a>
</li>
<li class="page-item ">
<a class="page-link" href="/demo-jekyll/pages/blog-10">10</a>
</li>
<!-- Next Page. -->
<li class="page-item blog_next">
<a class="page-link" href="/demo-jekyll/pages/blog-6" rel="next">»</a>
</li>
</ul>
</nav>
We will achieve this with Jekyll code.
3: Navigation: Number
Pagination by number is also simple.
Partial: Pagination Number
{% capture spaceless %}
{% if page.paginate_root == nil %}
{% assign paginate_root = "/" %}
{% else %}
{% assign paginate_root = page.paginate_root %}
{% endif %}
{% assign total_pages = paginator.total_pages %}
{% assign page_number = paginator.page %}
{% endcapture %}
<nav aria-label="Page navigation">
{% if total_pages > 1 %}
<ul class="pagination justify-content-center">
<!-- Page numbers. -->
{% for page in (1..total_pages) %}
<li class="page-item {% if page == page_number %} active{% endif %}">
{% if page == page_number %}
<span class="page-link">
{{ page }}
</span>
{% elsif page == 1 %}
<a class="page-link"
href="{{ site.baseurl }}{{ paginate_root }}"
>1</a>
{% else %}
<a class="page-link"
href="{{ site.paginate_path | relative_url | replace: ':num', page }}"
>{{ page }}
</a>
{% endif %}
</li>
{% endfor %}
</nav>
Case of Page in Loop
There are three cases for this pagination
- Active Page: No hyperlink. With additionalactive class.
<span class="page-link">
{{ page }}
</span>
- First Page: Because Jekyll use base path that different with paginate_path.
<a class="page-link"
href="{{ site.baseurl }}{{ paginate_root }}"
>1</a>
- The Rest: using paginate_path.
<a class="page-link"
href="{{ site.paginate_path | relative_url | replace: ':num', page }}"
>{{ page }}
Separate Logic
paginate_root lost in loop
There is a little issue, that the value of paginate_root, become nil inside the loop. So we have to define it, in a variable, in the first place.
{% capture spaceless %}
{% if page.paginate_root == nil %}
{% assign paginate_root = "/" %}
{% else %}
{% assign paginate_root = page.paginate_root %}
{% endif %}
{% assign total_pages = paginator.total_pages %}
{% assign page_number = paginator.page %}
{% endcapture %}
Now we can have the correct value of paginate_root.
Browser: Pagination Preview
How does it works ?
Just a simple loop.
{% for page in (1..total_pages) %}
<li class="page-item {% if page == page_number %} active{% endif %}">
...
</li>
{% endfor %}
4: Navigation: Previous and Next
Consider give it a prev and next button. The code is very similar with our previous article, with a few differences.
- Previous Page
<!-- Previous Page. -->
{% if paginator.previous_page %}
<li class="page-item blog_previous">
<a class="page-link"
href="{{ site.baseurl }}{{ paginator.previous_page_path }}"
rel="prev">«</a>
</li>
{% else %}
<li class="page-item blog_previous disabled">
<span class="page-link">«</span>
</li>
{% endif %}
- Next Page
<!-- Next Page. -->
{% if paginator.next_page %}
<li class="page-item blog_next">
<a class="page-link"
href="{{ site.baseurl }}{{ paginator.next_page_path }}"
rel="next">»</a>
</li>
{% else %}
<li class="page-item blog_next disabled">
<span class="page-link">»</span>
</li>
{% endif %}
Browser: Pagination Preview
Changes
That code above is using:
-
symbol « instead of previous word.
-
symbol » instead of next word.
Notice that, we also have additional stylesheet named
-
blog_previous, and
-
blog_next
Complete Source
Complete source code for this artefact available at:
-
- /_includes/pagination/02-number.html
- gitlab.com/…/_includes/pagination/02-number.html
5: Stylesheet: Before and After
Consider define these pagination stylesheet:
-
- _sass/themes/oriclone/_pagination.scss
- [gitlab.com/…/_pagination.scss][tutor-jekyll-sass-pagination].
.blog_previous {
span:after,
a:after {
content: " previous"
}
}
.blog_next {
span:before,
a:before {
content: "next "
}
}
And add the new pagination scss in main file.
-
- _sass/themes/oriclone/main.scss
- [gitlab.com/…/main.scss][tutor-jekyll-sass-main].
@import
...
// custom: general
"layout",
"decoration",
"stripes",
"list",
"pagination",
...
;
Browser: Pagination Preview
6: Stylesheet: Responsive
Pure CSS
You can make this responsive by using standard css
@media only screen and (min-width: 768px) {
...
}
Or as complete scss would be:
@media only screen and (min-width: 768px) {
.blog_previous {
span:after,
a:after {
content: " previous"
}
}
.blog_next {
span:before,
a:before {
content: "next "
}
}
}
Bootstrap Mixins
By the help of mixins/breakpoints, we can rewrite it in bootstrap style.
@include media-breakpoint-up(md) {
...
}
Or as complete _pagination.scss would be as below:
-
- _sass/themes/oriclone/_pagination.scss
- gitlab.com/…/_pagination.scss.
@include media-breakpoint-up(md) {
.blog_previous {
span:after,
a:after {
content: " previous"
}
}
.blog_next {
span:before,
a:before {
content: "next "
}
}
}
Do not forget to add mixins/breakpoints.
@import "vendors/bootstrap/mixins/breakpoints";
So we have the complete main.scss as below.
-
- _sass/themes/oriclone/main.scss
- gitlab.com/…/main.scss.
@import
// variables
"vendors/bootstrap/functions",
"variables",
"vendors/bootstrap/variables",
"vendors/bootstrap/mixins/breakpoints",
"vendors/bootstrap/mixins/image",
"vendors/bootstrap/mixins/gradients",
"vendors/bootstrap/mixins/transition",
"vendors/bootstrap/mixins/box-shadow",
// taken from bootstrap
"sticky-footer-navbar",
"bootstrap-custom",
// custom: general
"layout",
"decoration",
"stripes",
"list",
"pagination",
// custom: post
"post-navigation",
"post-calendar",
"post-header",
"post-content",
"post-code",
"post-highlight-jekyll"
;
7: Math: Algebra
The next article require complex logic. thus, we need to approach mathematic right away.
Assumption
Consider an example, a blog post contain ten posts.
In Jekyll Liquid we have:
{% assign total_pages = paginator.total_pages %}
For this math example, we can write the variable as below:
# CONST
$totalPost = 10
Table
We can also achieve $totalPages by ceiling division. And the result is on this table below.
# ALGEBRA
+--------------+-------+-------+-------+-------+-------+
| $pagination | 1 | 2 | 5 | 7 | 10 |
+--------------+-------+-------+-------+-------+-------+
| VARIABLE |
| $division | 10.0 | 5.0 | 2.0 | 1.4 | 1 |
| $totalPages | 10 | 5 | 2 | 2 | N/A |
+--------------+-------+-------+-------+-------+-------+
Of course, we do not need to show any pagination, if there is only one page for all result. That is why we can optionally, convert 1 into N/A.
What is Next ?
Consider continue reading [ Jekyll Pagination - Adjacent ].
Thank you for reading.