Pagination

Learn

January 21, 2022

The pagination component adds clever pagination to your page or Timber Posts Module.

When running a posts query through the Timber Posts Module, the Timber Query context contains the pagination parameters for that query. Using the posts.pagination.current and posts.pagination.total values in combination with the query.vars.posts_per_page that we have set we can have it generate paginated links.

To prevent an overload of link items, these are generated dynamically, showing only a limited amount of links at a time.

The pagination component generates it's own container, which is needed for the control elements. The component makes use of the ts_load_more action, which enables you to load twig templates. This does require you to register a hook that tells which twig-template to use for the 'template' variable. This is done so to not give away too much of the server setup.

Fieldname Description
container Unique container name for the page. A div with an id "pagination-{container}" will be created automatically.
template Template name that renders the requested content. Like ajax calls, this is the last part of a filter hook, the actual template name needs to be added using PHP.
target id of the element where requested content will be placed.
current The current page that is in view.
total The total number of pages that make up the pagination.
callbackdelay ms to wait before doing the request, so that visitor has time to navigate to the desired page without constant ajax requests.
posts_per_page The amount of items per page, needed for calculating the offset.
args Additional arguments for the request that can be used by the template.

{%- import 'components/generic/pagination.twig' as Pagination -%}
<div id="pagination-posts" class="uk-child-width-1-4" uk-grid>
    {% for item in posts %}
    <div>
        <div class="uk-card uk-card-default uk-card-body uk-text-center">
            <h3>{{ item.title }}</h3>
            {{ item.preview.length(30).read_more( '' ) }}
            
        </div>
    </div>
    {% endfor %}
</div>
{{ Pagination.render( null, {
    container: 'here',
    template: 'load-more-page',
    target: 'pagination-posts',
    current: posts.pagination.current,
    total: posts.pagination.total,
    callbackdelay: 1000,
    posts_per_page: query.vars.posts_per_page,
} ) }}    


Add template path

In order to tell which template path to use for the templatename, you need to add a few lines of PHP.


add_filter( 'twig_ajax_template_load-more-page' , function( $value ) { return 'load-more-page.twig'; }  );
add_filter( 'twig_ajax_nopriv_template_load-more-page' , function( $value ) { return 'load-more-page.twig'; }  );


And finally the Twig file that handles the request. Parameters are sent to it using the POST method.


{# template accesible as 'load-more-page.twig' #}
{%- set start = tb.intval(request.post.offset) + 1 %}
{%- set end = tb.intval(request.post.offset) + tb.intval(request.post.posts_per_page) %}
{% for item in start..end %}
	<div>
    	<div class="uk-card uk-card-body uk-card-default uk-text-center">
    	{{ item }}
        </div>
    </div>
{% endfor %}

Another example


{%- import 'components/generic/pagination.twig' as Pagination -%}
<div id="pagination-posts" class="uk-child-width-1-4" uk-grid>
    {% for item in 1..12 %}
    <div>
        <div class="uk-card uk-card-default uk-card-body uk-text-center">
            {{ item }}
        </div>
    </div>
    {% endfor %}
</div>
{{ Pagination.render( null, {
    container: 'here',
    template: 'load-more-page',
    target: 'pagination-posts',
    current: 1,
    total: 70,
    callbackdelay: 1000,
    posts_per_page: 12,
} ) }}    


Beaverplugins

Web ninja with PHP/CSS/JS and Wordpress skills. Also stand-in server administrator, father of four kids and husband to a beautiful wife.
Always spends too much time figuring out ways to do simple things even quicker. So that you can benefit.