ssg  
Article Series

This article series contain few sections.


Obsolete Repository:
This article use obsolete repository. Please refer to below repository for a more recent articles.

Complete Repository

Where to Discuss?

Local Group

Preface

Goal: Pagination using Number.

Preview

This is what we want to achieve in this tutorial.

Jekyll Pagination: Stylesheet Before After

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:

  {% 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

Hugo Pagination: Number List

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">&laquo;</a>
      </li>
    {% else %}
      <li class="page-item blog_previous disabled">
        <span class="page-link">&laquo;</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">&raquo;</a>
      </li>
    {% else %}
      <li class="page-item blog_next disabled">
        <span class="page-link">&raquo;</span>
      </li>
    {% endif %}

Browser: Pagination Preview

Hugo Pagination: Symbol Previous Next

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:


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

Hugo Pagination: Stylesheet Before After


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:

@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.

@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.