Flask and Bootstrap 5 - Creating a macro for pagination

The Bootstrap pagination component looks like this:

<nav>
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="#">Previous</a></li>
    <li class="page-item"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
    <li class="page-item"><a class="page-link" href="#">Next</a></li>
  </ul>
</nav>

It has 3 main blocks, the previous page, the numbering and the next page; with this clear, let's create a macro in Jinja that we can easily reuse in any other module:

my_app\templates\macro\pagination.html

{% macro m_pagination(pagination, url='tasks.index') %}

<nav>
    <ul class="pagination justify-content-center">

        {% if pagination.has_prev %}
            <li class="page-item">
                <a class="page-link" href="{{ url_for(url,page=pagination.prev_num) }}" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
        {% endif %}


        {% for page in pagination.iter_pages() %}
            {% if page != pagination.page %}
                <li class="page-item">
                    <a class="page-link" href="{{ url_for(url,page=page) }}" aria-label="Previous">
                        <span aria-hidden="true">{{ page }}</span>
                    </a>
                </li>
            {% else %}
                <li class="page-item active">
                    <a class="page-link" href="#" aria-label="Previous">
                        <span aria-hidden="true">{{ page }}</span>
                    </a>
                </li>
            {% endif %}
        {% endfor %}

        {% if pagination.has_next %}
            <li class="page-item">
                <a class="page-link" href="{{ url_for(url,page=pagination.next_num) }}" aria-label="Previous">
                    <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        {% endif %}

    </ul>
</nav>

{% endmacro  %}

Remember that macros are a type of functions that we have available in Jinja and through them we can supply parameters, which would be the data variable, in this example, the pagination object and a URL; as a consideration, we branched using a conditional to mark the active page and suspend navigation to itself:

{% if page != pagination.page %}
     <li class="page-item">
        <a class="page-link" href="{{ url_for(url,page=page) }}" aria-label="Previous">
           <span aria-hidden="true">{{ page }}</span>
        </a>
      </li>
{% else %}
      <li class="page-item active">
          <a class="page-link" href="#" aria-label="Previous">
             <span aria-hidden="true">{{ page }}</span>
          </a>
      </li>
{% endif %}

To use it, for example, from the task list:

my_app\tasks\controllers.py

def index(): 
   return render_template('dashboard/task/index.html', tasks=operations.pagination(request.args.get('page', 1, type=int)))

As you can see, we are receiving an argument for the URL; that is, of type GET called page:

request.args.get('page')

We indicate a default value, to avoid comparing with null values:

request.args.get('page', 1)

And the type, which by default is String:

request.args.get('page', 1, type=int)

And from the template:

my_app\templates\dashboard\task\index.html

{% extends "dashboard/master.html" %}
{% from 'macro/pagination.html' import m_pagination %}

***

{% block content %}
<table class="table">
    <tr>
        <td>Id</td>
        <td>Name</td>

        <td>Options</td>
    </tr>
    {% for t in tasks.items %}
    ***
</table>

{{ m_pagination(tasks) }}

{% endblock %}

And we will have:

Pagination in Bootstrap
Pagination in Bootstrap

- Andrés Cruz

En español

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.