0

Alright, I've made a bunch of themes over the years, and I've written a lot of queries. And I just realized that I apparently have no clue how to get multiple queries to behave. So, here is the loops from my index.php:

        <?php do_action( 'voodoo_pre_loop' ); ?>

        <?php if( is_home() ) : ?>

            <?php $args = array(
                'posts_per_page' => 1,
                'post__in' => get_option( 'sticky_posts' ),
                'ignore_sticky_posts' => 1
            );
            $my_query = new WP_Query( $args );
            while ($my_query->have_posts()) : $my_query->the_post();
            $do_not_duplicate = $post->ID; ?>
            <?php get_template_part( 'content', 'featured' ); ?>
            <?php endwhile; ?>

            <?php if ( is_active_sidebar( 'sidebar-2' ) ) : ?>
                    <?php dynamic_sidebar( 'sidebar-2' ); ?>
            <?php endif; ?>

            <?php $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
            $more_args = array(
                'posts_per_page' => 9,
                'post__not_in' => get_option( 'sticky_posts' ),
                'paged' => $paged
            );
            query_posts( $more_args ); ?>

        <?php endif; ?>

        <?php if ( have_posts() ) : ?>

            <?php voodoo_content_nav( 'nav-above' ); ?>

            <?php while ( have_posts() ) : the_post();
            if( $post->ID == $do_not_duplicate ) continue; ?>

                <?php $format = get_post_format();
                if ( false === $format )
                    $format = 'standard';
                    get_template_part( 'content', $format ); ?>

            <?php endwhile; ?>

            <?php voodoo_content_nav( 'nav-below' ); ?>

        <?php else : ?>

            <?php voodoo_else(); ?>

        <?php endif; ?>

So, what I expected to have happen, was to have a loop. It would just grab one post. If there was a sticky, we'd grab it. If not, then the most recent post. That would always farm out to content-featured for the display. This loop seems to work. I get a stick / or not if there aren't any. And content-featured is called. This is all in the is_home, because I only want it to happen on the home/ front page.

Still in is_home is a widget area. That ain't complicated.

Next up, a second loop. My logic, the query was still inside the is_home. On the front page, I wanted 9 posts, never any stickies, no duplicates of that first post. On subsequent pages, I figured I didn't need that query. I just want all the other pages to show my standard 10 posts. No featured thing, no sidebar, etc.

So where this seems to get me, is that first post, the widget, and a mess.

That second area, I only ever get 7 posts. On subsequent pages, I still get that first featured loop which I don't want. And I only get 8 posts. I have read all over the internet, and I'm obviously not grasping something.

Any ideas: Why is_home or is_front_page won't work here? Why I can't get my numbers right? (1+9 posts is home, 10 posts remaining pages)

I'd love a little help here so I can understand this all a bit better. Thanks!

2
  • 2
    'On subsequent pages' - does this refer to paginated pages of the front page? in which case, you might need to use is_home && !is_paged() in the conditional.
    – Michael
    Commented Nov 17, 2011 at 23:21
  • Yup paginated pages. I'll try that and report back, thanks! Commented Nov 18, 2011 at 1:04

1 Answer 1

3

The first query should be reset with wp_reset_postdata() after its loop has finished to avoid conflicts with the main query. Glancing over your code, that's the most important flaw I see.

Also, I'd use $my_query_2 = new WP_Query( $more_args ); for the second one - I don't see why it'd be better to revert back to using query_posts(). This might be worth a read.

While were at it: It shouldn't affect the functionality of your code at all, but why in the world are there so many php opening and closing tags (i.e. <?php and ?>) ? That might make sense if you have HTML markup in between and dislike echoing, but given that that's not the case, just put <?php at the top of the document (or the relevant section) and ?> at the bottom. It will make for more legible code both for you yourself as well as people helping you.

EDIT: Mkay. This works as expected on my dev install:

<ul>            
<?php
    $per_page = is_paged() ? 10 : 9;
    $stickies = get_option( 'sticky_posts' );
    $offset = empty( $stickies ) ? 1 : 0;
    if( is_home() && !is_paged() ) {
        $per_page = 9;
        $args_first_query = array(
            'posts_per_page' => 1,
            'post__in' => $stickies,
            'ignore_sticky_posts' => 1
        );
        $first_query = new WP_Query( $args_first_query );
        if( $first_query->have_posts() ) {
            while ($first_query->have_posts()) : $first_query->the_post();
                // replace with your template part:
                echo '<li>Latest Sticky:'.get_the_title().'</li>';
            endwhile;
        }
        wp_reset_postdata();
    }
    // your sidebar
    $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
    $args_main_query = array(
        'posts_per_page' => $per_page,
        'post__not_in' => $stickies,
        'paged' => $paged,
        'offset' => $offset
    );
    query_posts( $args_main_query );
    if( have_posts() ) {
        while ( have_posts()) : the_post();
            $format = get_post_format();
            if ( false === $format )
                $format = 'standard';
            echo '<li>'.get_the_title().'</li>';
        endwhile;
    }
    // pagination, with check for WP-PageNavi plugin
    if ( function_exists('wp_pagenavi') ) {
        wp_pagenavi();
    } elseif ( get_next_posts_link() || get_previous_posts_link() ) {
        next_posts_link( '&laquo; Older Entries' );
        previous_posts_link( 'Newer Entries &raquo;' );
    }
    wp_reset_query();
?>
</ul>

I'd suggest you check whether the above works on your site as well. If it does, drop your custom stuff in one by one, see whether it fails and if so, when.

This check if( $post->ID == $do_not_duplicate ) continue; is definitely superfluous, given that the first query only takes stickies and the second one doesn't at all. So you can for sure omit that line and the related one in the 1st query.

11
  • Thanks for the tips. The query setup came directly from the codex, it's nearly identical including lack of resetting. I did try reseting the queries earlier. As for the code, I'll clean it up. I pretty much hack things together as I think of them, and then clean everything up later. I'll try out the tips and report back. Also, voodoo_pre_loop does nothing. It's for later use. Commented Nov 18, 2011 at 1:06
  • Alright, I used wp_reset_postdata after the first loop. Also tried switching out to a new MY_Query instead of query_posts. None of that made any difference. I've got my conditional working per the suggestion above, but I'm now getting 1+7 posts on the homepage and 9 on the paginated pages. instead of 1+9, and 10. Any more ideas? Thanks so far! Commented Nov 18, 2011 at 1:58
  • Here's my train of thought. That second query for 9 posts is inside the conditional still. So I thought it would only execute on is_home. That's why I assumed I would get 1+9 posts. Outside of the homepage, that entire first query shouldf be ignored (it is) and the second query should be ignore too, giving me my default posts count of 10 on paginated pages. Instead, I ask for 9 on fron page and get 7, and I want 10 on other pages, get 9. Commented Nov 18, 2011 at 12:16
  • @Rev.Voodoo Mkay. Instead of attempting to debug your code, I quickly rewrote and tested it in my dev environment. Works - see the edit. I couldn't copy yours and test that, cause it's got to much stuff specific to your theme. I suggest you test the above and adapt it back to your customization, if it works for you as well. Should just output a list of post titles. Am getting 10 and 10, as expected. Commented Nov 18, 2011 at 13:54
  • I'm getting 10 on the first page, and 9 on subsequent pages (I did verify that my WP settings were at 10 per page). Also, that first loop isn't intended to get only stickies. It grabs a sticky if one exists, otherwise it grabs the latest normal post. This loop is better than what I had for sure, appreciate the effort for real! I really want to nail down ensuring I get exactly the # of posts I query, so I can plan the layout around it. Commented Nov 18, 2011 at 14:02

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