WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Custom Post Type loop posts_per_page not working (7 posts)

  1. TrishaM
    Member
    Posted 2 months ago #

    I need help with getting a loop for a CPT working.

    Here's the problem: If I use a "foreach" statement instead of a "if/while" statement, it returns results but the post_per_page does not work (same with using numberposts) - I get a few results, but not the number I'm calling for. If I use posts_per_page=-1 I get all results, but I want to use it in a sidebar and limit it to 5 posts. I get either 2 or 3 posts returned when there are 8 total it *could* return, leaving me scratching my head.

    If I use "if/while", I get no results. No error, just no results.

    I'm trying to show future scheduled events for a custom post type setup for "Hikes". I'm using a custom field for the future date ('hike_date_start'), and converting that date to a timestamp using strtotime, then comparing it to the current date to show only those that are greater-than or equal to current date. It works great on the Page for all the hikes when I use posts_per_page=-1. All future scheduled posts display correctly.

    However, when I take that SAME query/loop and put it in a widget (PHP Code widget) to show it in the sidebar, the ONLY modification is that I change posts_per_page=-1 to posts_per_page=5. I also (because I'm using it as a secondary loop in the sidebar) add wp_reset_query to the beginning and end.

    Here's my sidebar code:

    wp_reset_query();
    global $post;
    $myposts = query_posts('post_type=hike&meta_key=hike_date_start&orderby=meta_value_num&order=ASC&posts_per_page=5');
    foreach ( $myposts as $post ) : 
    
    $exp_date = strtotime(get_post_meta($post->ID,'hike_date_start',true));
    $today = time();
    if ($today <= $exp_date) {
    ?>
    ...(do stuff)...
     } endforeach; wp_reset_query();

    And yet even though the only difference is that I want to restrict the result to just the 5 posts, it only returns 3. I could understand if I got none, or 8 (the number of actual posts), but why 3? Why does it work perfectly on a Page, but not in a sidebar?

  2. alchymyth
    The Sweeper & Moderator
    Posted 2 months ago #

    query_posts() is commonly used with a loop of while( have_posts() ) : the_post(); as opposed to a foreach loop which would be based on get_posts()

    review http://codex.wordpress.org/The_Loop

    also, for secondary lops, use WP_Query() rather than query_posts() - http://wordpress.stackexchange.com/questions/1753/when-should-you-use-wp-query-vs-query-posts-vs-get-posts?rq=1

  3. TrishaM
    Member
    Posted 2 months ago #

    Thanks @alchymith, I appreciate the response. It takes me back to where I started :-)

    I started out using get_posts then changed to query_posts based on advice I found elsewhere (stack exchange I think)….because it was suggested to me that by not doing a new query I was not getting all the results…..I did find that by using new WP_Query I can use the if/while statement, however, even after changing that I still get only 3 out of 8 possible results instead of the 5 I request in post_per_page.

    SO here's the modified code:

    wp_reset_query();
    global $post;
    $args = array(
    'post_type' => 'hike',
    'meta_key' => 'hike_date_start',
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'posts_per_page' => 5,
    );
    $myposts = new WP_Query( $args);
    if ( $myposts->have_posts() ) : while ( $myposts->have_posts() ) : $myposts->the_post(); {
    
    $exp_date = strtotime(get_post_meta($post->ID,'hike_date_start',true));
    $today = time();
    if ($today <= $exp_date) {
    
    …(do stuff)….
    
    } } endwhile; endif; wp_reset_query();

    I am using wp_reset_query because this is the third query/loop on the page - there is a query in the header to setup a post slider, one for the main content that pulls posts from a category, and then this sidebar query to list posts from a custom post type (hikes).

    Each of the first two loops calls for only 3 posts - so my best guess is that's what is messing with this loop, but isn't wp_reset_query supposed to clear any prior queries and start over, including the results called for by posts_per_page? Also, the second loop on the page uses a loop counter so that I can do something different with the first result than with the second/third results.

  4. vtxyzzy
    Member
    Posted 2 months ago #

    I am guessing a bit, but I think the problem may be that you are using an 'if' inside the loop and printing only future-dated posts, but the query may return some past-dated posts.

    I believe you need to add a 'meta_compare' to your query args to select only the posts that you actually want to display.

  5. TrishaM
    Member
    Posted 2 months ago #

    Thanks @vtxyzzy - I suppose I should have put on my original post that I'm not a programmer, so it's all a little confusing to me, BUT that said, I thought that you can only use meta_compare with dates if you have a timestamp to work with….

    The custom field that holds the (future) date of the hike is formatted yymmdd so I have to do a strtotime function first to convert that to a timestamp in order to compare it to whatever is the current date (today)……and I first have to fetch the posts in order to get that field's data in order to convert it, yes?

    Is there a way to use meta_compare in the query before I have the converted date-to-timestamp?

    The way I have it now DOES actually return Posts correctly (I don't get past-dated hikes) it just doesn't give me the number of posts I requests using posts_per_page….

  6. vtxyzzy
    Member
    Posted 2 months ago #

    Just format the 'meta_value' argument as 'yyyymmdd':

    'meta_value' => date('Ymd'),
    'meta_compare' => '>',
  7. TrishaM
    Member
    Posted 2 months ago #

    SUCCESS! Thank you very much, @vtzyzzy (how do you pronounce that anyway?)

    SO in case anyone else is struggling with this, here is the final code snippet below that works:

    In this query I'm pulling a Custom Post Type (for Guided Hikes) that uses a custom field to store the scheduled Hike Date, then limiting results to only Hikes that are schedule in the future (equal or greater to whatever 'today's' date is), and further limit the results by xx number of posts using posts_per_page.

    wp_reset_query();
    global $post;
    $args2 = array(
    'post_type' => 'hike',
    'meta_key' => 'hike_date_start',
    'meta_value' => date('Ymd'),
    'meta_compare' => '<=',
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'posts_per_page' => 5,
    );
    $myposts = new WP_Query( $args2 );
    if ( $myposts->have_posts() ) : while ( $myposts->have_posts() ) : $myposts->the_post(); {
     // I kept the next line in so I can convert the hike date to a timestamp and then display that date in a different way e.g. 'Saturday the 19th of June'...
    $exp_date = strtotime(get_post_meta($post->ID,'hike_date_start',true));
    ?>
    ….do stuff…(.here I list just the post titles as permalinks with the hike date below)
    <?php }  endwhile; endif; wp_reset_query();

Reply

You must log in to post.

About this Topic