1

I have a query that loops through <li>'s and displays the number of <li>'s I have. Is there a way I can make the loop pull 2 <li>'s at a time rather than one?

// 5 list items
<ul>
<?php while(has_posts()): the_post(); ?>
    <li>
        <div class="slide"><?php the_content(); ?></div>
    </li>
<?php endwhile; ?>
</ul>

output

<ul>
    <li><div class="slide">content 1</div></li>
    <li><div class="slide">content 2</div></li>
    <li><div class="slide">content 3</div></li>
    <li><div class="slide">content 4</div></li>
    <li><div class="slide">content 5</div></li>
</ul>

and how I would like it to output...

<ul>
   <li>
       <div class="slide">
           content 1
           content 2
       </div>
   </li>
   etc...
</ul>

I hope you understand what I am trying to do.

Thanks!

  • 2
    You could find the info you need via google.... (poor search terms, but the basic principle of what you need is still there, determine when X is multple of Y and do Z).. – t31os May 2 '13 at 21:02
  • 2
    This is effectively the same question as here: wordpress.stackexchange.com/questions/96943/… I provided what I believe to be a very effective generic solution for this kind of Loop structure. – s_ha_dum May 2 '13 at 21:17
2

Easy using WP query (get to know it...)

<ul>
    <?php
        $recentPosts = new WP_Query();
        $recentPosts->query('showposts=2'); // SET AMOUNT HERE
    ?>
    <?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
        <li><div class="slide"><?php the_content(); ?></div></li>
    <?php endwhile; ?>
</ul>

Hope this helps. Let me know if you encounter any issuse.


EDIT 1:
* explenation - just added a small conditional counter

<ul>
    <?php 
        $count = 1;
        while(has_posts()): the_post(); 
    ?>

        <?php if ($count == 1) {echo '<li><div class="slide">';} ?>
        <?php the_content(); ?>
        <?php if ($count == 3) {echo '</div></li>'; $count = 1;} else {$count++;} ?>

    <?php endwhile; ?>
</ul>

EDIT 2:
* please note i changed has_post to have_post (think it should be that way? your call)

<?php 
    echo '<ul>';
    $count = 1;

    while(have_posts()): the_post(); 

    if ($count == 1) {$slideOpenTag = '<li><div class="slide">';} else {$slideOpenTag = '';}
    if ($slideOpenTag) {echo $slideOpenTag;}

    the_content();

    if ($count == 3) {$slideCloseTag = '</div></li>'; $count = 1;} else {$count++; $slideCloseTag = '';}
    if ($slideCloseTag) {echo $slideCloseTag;}

    endwhile;
    if (!$slideCloseTag) {echo '</div></li>';}
    echo '<ul>';        
?>
  • I think you misunderstood my question. I don't want to display JUST 2 items, I want the loop to display 2 items at a time in the same div. Make sense? – Romes May 2 '13 at 20:58
  • sure, revising... 2 minutes :) – Sagive SEO May 2 '13 at 20:59
  • do I need to increment the count? e.g. ++$count; – Romes May 2 '13 at 21:09
  • wow... left my head somewhere - fixed it (your right of course.) – Sagive SEO May 2 '13 at 21:10
  • also good to note that this is a fast readble solution. while writing this i wish i had a place to test small stuff like that so i could offer a complete answer... so i think this inspired me and would create a local installation for small testings like that ;) – Sagive SEO May 2 '13 at 21:13
3

Drawing on Sagive SEO's post this also seems to work without using counters.

echo '<ul>';

while ( have_posts() ) {
    echo '<li><div class="slide">';

    the_post();
    the_content();

    // If there is 1 more post, advance current post and add its content.
    if ( $wp_query->current_post + 1 < $wp_query->post_count ) {
        the_post();
        the_content();
    }

    echo '</div></li>';
}

echo '</ul>';

The WordPress function the_post() advances the $wp_query object post index, just like the next_post() WP_Query object method does. Adding a second call to the_post() affects the value of the have_posts() function.

This loop process two posts per loop instead of one unless an odd number of posts are returned in which case the conditional will be false and only the last post will be processed on the last loop pass.

EDIT: Some Math for 7 total posts.

$wp_query->post_count = 7

$wp_query->current_post The index of the post currently being displayed (starting with 0).

Pass one. The first the_post() initializes $wp_query->current_post to 0. if ( 0 + 1 < 7 ). The conditional the_post() increments $wp_query->current_post to 1.

Pass two. The first the_post() increments $wp_query->current_post to 2. if ( 2 + 1 < 7 ). The conditional the_post() increments $wp_query->current_post to 3.

Pass three. The first the_post() increments $wp_query->current_post to 4. if ( 4 + 1 < 7 ). The conditional the_post() increments $wp_query->current_post to 5.

Pass four. The first the_post() increments $wp_query->current_post to 6. if ( 6 + 1 < 7 ). The conditional is false and does not execute.

  • Very nice - much cleaner - but - doesnt work ;( (tested it) - do the math (7 posts === (cur=1+1)<7 RESULT=run) ELSE (7 posts === (cur=2+1)<7 RESULT=run) - Runs every time unless 1 before last. Am i missing something? – Sagive SEO May 3 '13 at 15:50
  • I worked for me using 3 posts. If you use it from a function you need to make $wp_query global. See the edit above for the math. – Charles Clarkson May 3 '13 at 23:53
  • yee but he wanted this>> [box] {content}{content}{content} [/box] & again... NM mate - just that using the $wp_query->post_count along with not extra calculation wont do but its a great approach -> maybe somthing like >> if ( ($wp_query->current_post + 1) % 3 == 0) is the right way – Sagive SEO May 4 '13 at 10:37
  • Romes says he wants <div>{content}{content}</div>. Two contents, not three. Each pass of the loop advances the post index twice. Once for each post. If an odd number of posts are returned in the query then the last pass of the loop will attempt to grab a post which doesn't exist. The conditional prevents that. – Charles Clarkson May 4 '13 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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