A way to detect which page a post is on

I’m wondering if there is a good way to tell which archive page a post came from. I essentially just need the post’s position in the total order, then divide it by the ‘posts_per_page’ option. The hangup I’m having is getting that position or offset of where the post sits.

EDIT: All while being on the SINGLE POST template.

Read More

There, no matter what, the usual $wp_query global and ‘page’/’paged’ query vars are always 0 – so those won’t get me anywhere.

Related posts

Leave a Reply

5 comments

  1. Alright, nevermind. I got this solved by doing this at the top of the single post template:

    $position_query = array( 'post_type' => 'portfolio', 'orderby' => 'menu_order', 'order' => 'ASC', 'numberposts' => -1 );
    $position_posts = get_posts($position_query); $count = 0;
    foreach ($position_posts as $position_post) { $count++;
        if ($position_post->ID == $current_id) { $position = $count; break; }
    }
    $posts_per_page = get_option('posts_per_page');
    $result = $position/$posts_per_page;
    $current_page = ceil($result);
    
  2. If you’re on page 2+, you’ll have access to the global $page, which should tell you the pagenumber you’re currently on. There’re also some others that are worth a look (never know where which one is present/active): global $multipage, $numpages;.

    You can also check the current page via the get_query_var(); core function. Basically the global $page comes from there.

    // Using get_query_var()
    $paged = get_query_var('page') ? get_query_var('page') : false;
    
    // Or via the global wp_query object
    $paged = $GLOBALS['wp_query']->query_vars['page'] ? $GLOBALS['wp_query']->query_vars['page'] : false;
    
    if ( $paged )
        // do stuff - @example echo "Current page is {$paged}";
    
  3. I needed something like this for singles only and slightly simplified the accepted answer:

      $position_query = array( 'post_type' => 'post','order'=>'DESC', 'numberposts' => -1 );
      $position_posts = get_posts($position_query); $count = 0;
    
      foreach ($position_posts as $position_post) { $count++;
            if ($position_post->ID == $post->ID) { $current_page = $count; break; }
       }
    
      $total_posts = count($position_posts);
    

    This can used in this context: ‘Page 1 of 10’ 1 being $current_page and 10 being $total_posts

  4. When faced with this same requirement I opted to use a direct MySQL call to calculate which page the current post is on without retrieving and looping every post in this post_type. I went this route because I discovered it is much faster when working on a site with thousands of posts.

    This approach may also be put inside a function/method and determined from anywhere.

    function which_page_is_this_post_on( WP_Post $post ) : int {
        global $wpdb;
        return $wpdb->get_var( $wpdb->prepare( "SELECT CEIL(COUNT(*) / %d) from {$wpdb->posts} WHERE `ID` <= %d and post_type=%s and post_status='publish'", get_option( 'posts_per_page' ), $post->ID, $post->post_type ) );
    }
    

    If you find you are calling it often (like within a template) you can store the result in the object cache if desired.

    function which_page_is_this_post_on( WP_Post $post ) : int {
        global $wpdb;
        $cached = wp_cache_get( __FUNCTION__ . $post->ID );
        if ( ! $cached  ) {
            $cached = $wpdb->get_var( $wpdb->prepare( "SELECT CEIL(COUNT(*) / %d) from {$wpdb->posts} WHERE `ID` <= %d and post_type=%s and post_status='publish'", get_option( 'posts_per_page' ), $post->ID, $post->post_type ) );
            wp_cache_set( __FUNCTION__ . $post->ID, $cached, 15 * MINUTE_IN_SECONDS );
        }
        return $cached;
    }
    
  5. We have 2 Conditional Tags to make this simpler

     <?php if(is_single())
        {
        echo "post";
        }
        elseif(is_page())
        {
        echo "page";
        } ?>
    

    Paste This in the File which includes in both page and post and changed from “post” & “Page” to whatever your need is.