'Timber: Single post pagination does not work (wp_link_pages)

I am fairly new to Timber and I am trying to get the pagination for a single post item working. Since there are a lot of topics around the pagination for archives, I want to underline that this is about a single post pagination, that handles a multi-page single post created with <!--nextpage--> tags. In basic WordPress/PHP usage it is handled with wp_link_pages() inside the loop.

As far as I understood, by searching SO and other websites, the magic should happen by just using the post.pagination array. But it's empty inside my twig file (and according to the Timber documentation does not exist at all inside the Timber\Post object).

My singular.php header looks like this:

$context     = Timber::get_context();
$post_object = new Timber\Post();

And here is my twig file:

{% if post.pagination %}

    <nav>Pages:

        {% for page in post.pagination.pages %}

            {% if page.current %}

                <span class="current">{{ page.title }}</span>{{ loop.last ? '' : ', ' }}

            {% else %}

                <a href="{{ page.link }}">{{ page.title }}</a>{{ loop.last ? '' : ', ' }}

            {% endif %}

        {% endfor %}

    </nav>

{% endif %}

What am I doing wrong, what am I missing, how can I get the single post pagination to work with Timber?



Solution 1:[1]

For single post pagination to work Timber v1, you need to use the older Timber::query_post() function instead of new Timber::get_post().

$context         = Timber::context();
$timber_post     = Timber::query_post(); // not Timber::get_post();
$context['post'] = $timber_post;

If you do this, then these should work as expected:

{{ post.paged_content }}

Returns the content of the current page of a multi-page post. On a post without page breaks this will return the full content.

{{ post.pagination }}

Returns a Timber/Pagination object for a multi-page post, or an empty array for a post without page breaks.

You don't need this, but it might be useful.

if ( $multipage ) {
    $context['post']->post_content = $pages[$page - 1];
}

The point of this code would be to allow you to use {{ post.content }} instead of {{ post.paged_content }}. Otherwise {{ post.content }} will return the whole post, even if there is pagination.

Note

This only applies to Timber V1. I have not experimented with Timber V2, because it is still being developed, but this issue is apparently fixed in that version, and Timber::post_query has been removed.

Reference:

Solution 2:[2]

To make wp_link_pages() work as you expect add these lines to your singular.php

global $post, $page, $pages, $multipage;
setup_postdata( $post );

// setting up your context
$context         = Timber::context();
$context['post'] = new Timber\Post();

if ( $multipage ) {
    $context['post']->post_content = $pages[$page - 1];
}

Then in your twig file instead of post.content you should write post.paged_content to get page content

Solution 3:[3]

You have not correctly added post to the context:

$context = Timber::get_context();

$post            = new Timber\Post();
$context['post'] = $post;

An additional tool is {{ dump( post.pagination) }}, when debuggin is enabled, which will print the output for a variable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ihar Aliakseyenka
Solution 3 WPhil