7

Is there a way to query the number of pages/the last page of a single post which is paginated by <!--nextpage--> on wordpress?

function count_post_pages($post_id) {
    $the_post = get_post($post_id);
    return count(explode('<!--nextpage-->', $the_post->post_content));
}

I am not sure whether this is the right of way of doing it, but can someone help...

3 Answers 3

3

Inside the loop, as michael pointed out you could just refer to $numpages global variable.

Outside of the loop, your code is almost fine.

Being the number of the pages the number of <!--nextpage--> + 1, you could save a function call by doing:

$numOfPages = 1 + substr_count($the_post->post_content, '<!--nextpage-->');

As a quick and not-that-dirty solution that is totally fine.

However, that code would not take into account filters and other minor things (e.g. <!--nextpage--> at the very start of the post content is ignored).

So to be 100% compatible with core code, your function should be something like:

function count_post_pages($post_id) {
    $post = get_post($post_id);
    if (!$post) {
       return -1;
    }

    global $numpages;
    $q = new WP_Query();
    $q->setup_postdata($post);

    $count = $numpages;

    $q->reset_postdata();

    return $count;
}

This is 100% compatible with core code, but also is more "expensive" and triggers more hooks than you actually need (with possibly unexpected side effects).

The third solution would be:

function count_post_pages($post_id) {
    $post = get_post($post_id);
    if (!$post) {
       return -1;
    }

    $content = ltrim($post->post_content);
    // Ignore nextpage at the beginning of the content
    if (strpos($content, '<!--nextpage-->') === 0) {
         $content = substr($content, 15);
    }

    $pages = explode('<!--nextpage-->', $content);
    $pages = apply_filters('content_pagination', $pages, $post);

    return count($pages);
}

This solution is relatively "cheap" and it is 100% core compliant... for now, in fact, the issue with this code is that it duplicates some code that might change in future versions (e.g. the "content_pagination" filter was added in version 4.4, so quite recently).

1
  • 1
    Thank you so much for the detailed response, sorry I can not mark more than one answer correct, it was really helpful, least i can do is up vote. Commented May 9, 2018 at 16:33
5

have a look at https://codex.wordpress.org/Global_Variables#Inside_the_Loop_variables

within the loop, the global variables related to the <!--nextpage--> tag are:

$page - the actual sub page,

$multipage - (boolean) =1 if nextpage was used

$numpages - total number of sub pages

0
1

When WordPress is using pagination like this, there's a query variable $paged that it keys on. So page 1 is $paged=1 and page 15 is $paged=15.

You can get the value of this variable with the following code:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1; Getting the total number of pages is a bit trickier. First you have to count all the posts in the database. Then filter by which posts are published (versus which are drafts, scheduled, trash, etc.). Then you have to divide this count by the number of posts you expect to appear on each page:

$total_post_count = wp_count_posts(); $published_post_count = $total_post_count->publish; $total_pages = ceil( $published_post_count / $posts_per_page ); I haven't tested this yet, but you might need to fetch $posts_per_page the same way you fetched $paged (using get_query_var()).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.