Render Bootstrap pagination links for a paged collection using shared configuration inputs.
View this pattern on the live demo site
Reusable pagination controls for lists and search results.
{% comment %}
Displays pagination links using bootstrap classes
Inputs:
collection - the collection to iterate over
page_param - the query parameter to use for pagination links
pagination_size - 'sm' or 'lg' (optional)
pagination_justify - 'start', 'center', or 'end'
max_pagination_links - the maximum number of pagination links to show (including the current page). Odd numbers work best.
hide_prev_and_next - true to hide the "Previous" and "Next" links
hide_first_and_last - true to hide the "first" and "last" links
disable_404_for_empty_collections - true to prevent returning a 404 response if there are no items in the collection past page 2 (ref: https://www.searchenginejournal.com/technical-seo/pagination/)
{% endcomment -%}
{%- var total_pages = collection.total_pages | at_least: 1 -%}
{%- var current_page = collection.page | default:1 -%}
{%- if current_page > total_pages -%}
{%- comment %}Intentionally set the current page to the total pages plus one so that the previous page link will correctly point to the last page in the collection{% endcomment -%}
{%- set current_page = total_pages | plus: 1 -%}
{%- unless disable_404_for_empty_collections %}{% set_response_code 404 "No Results" %}{% endunless -%}
{% endif -%}
{%- if total_pages > 1 or current_page > 1 -%}
{%- var page_param = page_param | default:'page' -%}
{%- var max_pagination_links = max_pagination_links | default: 11 | to_int | at_least: 1 -%}
{%- var back_page = current_page | minus:1 -%}
{%- var next_page = current_page | plus:1 -%}
{%- var first_page = 1 -%}
{%- var last_page = total_pages -%}
{%- if last_page > max_pagination_links -%}
{%- var offset = max_pagination_links | divided_by: 2 | floor -%}
{%- if current_page > offset -%}
{%- set first_page = current_page | minus: offset -%}
{%- endif -%}
{%- set last_page = first_page | plus: max_pagination_links | minus: 1 -%}
{%- if last_page > total_pages -%}
{%- set last_page = total_pages -%}
{%- set first_page = last_page | minus: max_pagination_links | plus: 1 -%}
{%- endif -%}
{%- endif -%}
<nav aria-label="Pagination">
<ul class="pagination flex-wrap{% if pagination_size == 'lg' or pagination_size == 'sm' %} pagination-{{pagination_size}}{% endif %}{% if pagination_justify == 'start' or pagination_justify == 'center' or pagination_justify == 'end' %} justify-content-{{pagination_justify}}{% endif %}">
{%- unless hide_first_and_last -%}
{%- if current_page > 1 -%}
<li class="page-item"><a class="page-link font-monospace" href="{% query_param_link = &page_param:false -%}" aria-title="First Page"><span aria-hidden="true">⏮</span></a></li>
{%- else -%}
<li class="page-item disabled" aria-hidden="true"><span class="page-link font-monospace">⏮</span></li>
{%- endif -%}
{%- endunless -%}
{%- unless hide_prev_and_next -%}
{%- if back_page < 1 -%}
<li class="page-item disabled" aria-hidden="true"><span class="page-link font-monospace">⏴</span></li>
{%- else -%}
{%- if back_page == 1 %}{% set back_page = false %}{% endif %}
<li class="page-item"><a class="page-link font-monospace" href="{% query_param_link = &page_param:back_page -%}" aria-title="Previous Page"><span aria-hidden="true">⏴</span></a></li>
{%- endif -%}
{%- endunless -%}
{%- for page_num in (first_page..last_page) -%}
{%- if current_page == page_num -%}
<li class="page-item active"><span class="page-link"><span class="visually-hidden">You're on page</span> {{page_num}}</span></li>
{%- else -%}
{%- var page_link = page_num %}{% if page_link == 1 %}{% set page_link = false %}{% endif -%}
<li class="page-item"><a class="page-link" href="{%- query_param_link = &page_param:page_link -%}" aria-label="Page {{page_num}}">{{page_num}}</a></li>
{%- endif -%}
{%- endfor -%}
{%- unless hide_prev_and_next -%}
{%- if next_page > total_pages -%}
<li class="page-item disabled" aria-hidden="true"><span class="page-link font-monospace">⏵</span></li>
{%- else -%}
<li class="page-item"><a class="page-link font-monospace" href="{% query_param_link = &page_param:next_page -%}" aria-title="Next Page"><span aria-hidden="true">⏵</span></a></li>
{%- endif -%}
{%- endunless -%}
{%- unless hide_first_and_last -%}
{%- if current_page < total_pages -%}
<li class="page-item"><a class="page-link font-monospace" href="{% query_param_link = &page_param:total_pages -%}" aria-title="Last Page"><span aria-hidden="true">⏭</span></a></li>
{%- else -%}
<li class="page-item disabled" aria-hidden="true"><span class="page-link font-monospace">⏭</span></li>
{%- endif -%}
{%- endunless -%}
</ul>
</nav>
{%- endif %}