The concept of dividing up a set of posts into a number of "pages" is called Pagination, and is controlled by a number of pagination parameters in a WordPress posts query. The three most relevant (and most commonly used) are:
posts_per_page
: the number of posts displayed on each page
paged
: which page of posts is currently being displayed (note that on a static front page and single posts broken up into "pages", the page number is represented by the page
parameter instead)
offset
: the number of posts to "skip over", or the number of posts on previous pages. This overrides the paged
parameter (and so the two are used in different circumstances) - but can usually be calculated from the other two parameters
WordPress provides the means to get the values of these query parameters by way of get_query_var()
, so you can retrieve them as such:
// Retrieve posts_per_page query variable defaulting to -1 to indicate all posts on one page
$posts_per_page = get_query_var( 'posts_per_page', -1 );
// Retrieve the page number from 'paged', defaulting to false if not found
$page_number = get_query_var( 'paged', false );
// If the page number couldn't be retrieved from 'paged', try 'page', and assume page number 1 if it can't be found there, either.
if( !$page_number )
$page_number = get_query_var( 'page', 1 );
// Retrieve the number of posts on previous pages, defaulting to 0
$offset = get_query_var( 'offset', 0 );
Knowing the values of those query arguments allows you to get the current post's index within paginated query results with either of the following expressions:
{number of previous posts} + {current post index within this page}
// OR, since {number of previous posts} = {number of posts per page} * {page number}:
{number of posts per page} * {page number} + {current post index within this page}
The only piece that's missing is {current post index within this page}
, which in your question you are acquiring by creating and incrementing the $count
variable - but here too WordPress provides another means to access this data within The Loop: the $current_post
property of the WP_Query
object, which can be accessed for the main query through the $query
global variable:
// Within The Loop, holds the index of the current post item within the query results array (starting from 0 for the first post)
$post_index = $query->current_post;
So, putting it all together into your Loop, the following should correctly list each post's index within paginated query results, regardless of how the query was set up (though it does not presently take into account the posts_per_archive_page
query parameter):
<?php
// Retrieve the number of posts from previous pages
$index_offset = get_query_var( 'offset', false );
// If the number of posts on previous pages could not be retrieved, calculate it
if( ! $index_offset ) {
// Retrieve posts_per_page query variable defaulting to -1 to indicate all posts on one page
$posts_per_page = get_query_var( 'posts_per_page', -1 );
/* Retrieve the page number, or assume page number 1 if it's not set anywhere (done here
in shorthand using the "tertiary operator") */
$page_number = get_query_var( 'paged', false )
? get_query_var( 'paged' )
: get_query_var( 'page', 1 );
// If pagination is enabled and we're not on the first page, calculate the offset
if( $posts_per_page > 0 && $page_number > 1 )
$index_offset = $posts_per_page * $page_number;
else
$index_offset = 0; // Otherwise, indicate that there are no posts before this page
}
// The Loop
while( have_posts() ) {
the_post();
/* Set the post index to it's position in the query results, PLUS the number of
posts on previous pages, and add 1 to start counting from 1 instead of 0 */
$post_index = $query->current_post + $index_offset + 1;
// Now display $post_index before the post's title:
?>
<div id="post_<?php the_ID(); ?>" <?php post_class(); ?>>
<h3 class="post-title"><?php echo( $post_index ); ?>. <?php the_title(); ?></h3>
<?php the_content(); ?>
</div>
<?php
} // End The Loop
?>