Skip to main content

As I already wrote in my comment 3 days ago something like this should work

{% paginate craft.entries.section('mySection').limit(10) as pageInfo, pageEntries %}

{% for page, url in pageInfo.getPrevUrls(3) %}
    <a href="{{ url }}">{{ page }}</a>
{% endfor %}

<span class="current">{{ pageInfo.currentPage }}</span>

{% for page, url in pageInfo.getNextUrls(3) %}
    <a href="{{ url }}">{{ page }}</a>
{% endfor %}

{% if pageInfo.totalPages - pageInfo.currentPage > 3 %}
    <span>...</span>

    <a href="{{ pageInfo.lastUrl }}">{{pageInfo.totalPages}}</a>
{% endif %}

[EDIT]: In the above script you will come across situations where the gap sometimes occurs between consecutive numbers, which can look silly.

Gap between consecutive numbers

Single page gap

To fix this you can add a little extra logic to it:

{% set amountVisible = amountVisible|default(2) %}
{% if pageInfo.currentPage > amountVisible + 1 %}
    <a href="{{ pageInfo.firstUrl }}">1</a>

    {% if pageInfo.currentPage == amountVisible + 3 %}
        <a href="{{ pageInfo.getPageUrl(2) }}">2</a>
    {% elseif pageInfo.currentPage > amountVisible + 3 %}
        <span>...</span>
    {% endif %}
{% endif %}

{% for page, url in pageInfo.getPrevUrls(amountVisible) %}
    <a href="{{ url }}">{{ page }}</a>
{% endfor %}

<span class="current">{{ pageInfo.currentPage }}</span>

{% for page, url in pageInfo.getNextUrls(amountVisible) %}
    <a href="{{ url }}">{{ page }}</a>
{% endfor %}

{% if pageInfo.totalPages - pageInfo.currentPage > amountVisible %}
    {% if pageInfo.totalPages - pageInfo.currentPage == amountVisible + 2 %}
        <a href="{{ pageInfo.getPageUrl(pageInfo.totalPages - 1) }}">{{pageInfo.totalPages - 1}}</a>
    {% elseif pageInfo.totalPages - pageInfo.currentPage > amountVisible + 1 %}
        <span>...</span>
    {% endif %}

    <a href="{{ pageInfo.lastUrl }}">{{pageInfo.totalPages}}</a>
{% endif %}

Now this added logic will do two things:

  1. If there is no gap, it won't render a thing.
  2. If the gap only amounts to one page it will render a page number instead.

This results in the following:

No more "useless" gaps

As an added bonus: if you add the amountVisible variable on top with a default value you can put this in a twig partial which you can then easily implement on the paged view like so:

{% include 'partials/pager' with { pageInfo: pageInfo, amountVisible: 3 } %}

(Note that passing pageInfo explicitly is not required, but I do it for the sake of completeness and to prevent accidental cleanups of "unused" vars.)

Robin Schambach
  • 19.8k
  • 1
  • 20
  • 45