Flask y Bootstrap 5 - Creación de un macro para la paginación de registros

El componente de paginación de Bootstrap luce como el siguiente:

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

Tiene 3 bloques principales, el de la página previa, la numeración y la página siguiente; teniendo esto claro, vamos a crear un macro en Jinja que podamos reutilizar fácilmente en cualquier otro módulo:

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

Recuerda que los macros son una especie de funciones que tenemos disponibles en Jinja y mediante la misma podemos suministrar parámetros, que seria la data variable, en este ejemplo, el objeto de paginación y una URL; como consideración, hicimos una bifurcación mediante un condicional para marcar la página activa y suspender la navegación a sí misma:

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

Para utilizarlo, por ejemplo, desde el listado de tareas:

my_app\tasks\controllers.py

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

Como puedes ver, estamos recibiendo un argumento por la URL; es decir, de tipo GET llamado page:

request.args.get('page')

Indicamos un valor por defecto, para evitar comparar con valores nulos:

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

Y el tipo, que por defecto es String:

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

Y desde el 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 %}

Y tendremos:

Paginación en Bootstrap
Paginación en Bootstrap

- Andrés Cruz

In english

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz En Udemy

Acepto recibir anuncios de interes sobre este Blog.