Wordpress, wrapping every X element
Page 1 of 1
Interinactive
VIP Member



Posts: 29448

PostPosted: Sun, 21st Dec 2014 00:39    Post subject: Wordpress, wrapping every X element
Hello

I have the following:

Code:

         <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            <?php $categories = get_the_terms( $post->ID, 'category' ); if ( $categories && ! is_wp_error( $categories ) ) : ?>
            <?php foreach ( $categories as $category ) : ?>
            <?php $catPosts = new WP_Query( array('category_name' => $category->slug, 'posts_per_page' => -1) ); if ( $catPosts->have_posts() ) : ?>

               <?php while ( $catPosts->have_posts() ) : $catPosts->the_post(); ?>
                  <article class="third">
                     <div class="article">
                        <div class="articleimg">
                           <div class="overlay"></div>
                           <div class="articlecat">
                              <?php foreach((get_the_category()) as $category) { echo $category->cat_name . ' ';}?>
                           </div>
                           <figure>
                              <img src="<?php the_field("featured_image"); ?>" width="330" height="181" alt="<?php the_title(); ?>" title="<?php the_title(); ?>" />
                           </figure>
                        </div>
                        <div class="articlecontent clearfix">
                           <div class="date">
                              <?php echo get_the_date('l, F j, o'); ?>
                           </div>
                           <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                           <div class="articlepreview">
                              <p><?php echo get_excerpt(140); ?></p>
                           </div>
                           <a class="more" href="#">Read More</a>
                        </div>
                     </div>
                  </article>
               <?php endwhile; ?>

            <?php endif; wp_reset_postdata(); ?>
            <?php endforeach; ?>
            <?php endif; ?>
         <?php endwhile; endif; ?>


These articles are displayed in rows of 3... and each 3 need to be wrapped in a div with a class of 'full'. Like this:

Code:
<div class="full clearfix">
   <article class="third">
   <!-- Other code -->
   </article>
      <article class="third">
      <!-- Other code -->
   </article>
   <article class="third">
      <!-- Other code -->
   </article>
</div>

<div class="full clearfix">
   <article class="third">
   <!-- Other code -->
   </article>
      <article class="third">
      <!-- Other code -->
   </article>
   <article class="third">
      <!-- Other code -->
   </article>
</div>

<div class="full clearfix">
   <article class="third">
   <!-- Other code -->
   </article>
      <article class="third">
      <!-- Other code -->
   </article>
   <article class="third">
      <!-- Other code -->
   </article>
</div>


Is there an easy way to handle this in the PHP so that I don't have to generate a bunch of nth-child selectors in CSS? If it's in CSS, sometimes the rows can break due to height changes.

I'd really rather just use display: flex Sad But I cannot.

Thanks for any help
Back to top
PumpAction
[Schmadmin]



Posts: 26759

PostPosted: Sun, 21st Dec 2014 08:55    Post subject: Re: Wordpress, wrapping every X element
Code:

         <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            <?php $categories = get_the_terms( $post->ID, 'category' ); if ( $categories && ! is_wp_error( $categories ) ) : ?>
            <?php foreach ( $categories as $category ) : ?>
            <?php $catPosts = new WP_Query( array('category_name' => $category->slug, 'posts_per_page' => -1) ); if ( $catPosts->have_posts() ) : ?>

               <?php while ( $catPosts->have_posts() ) : $catPosts->the_post(); ?>
               <div class="full clearfix">
                  <article class="third">
                     <div class="article">
                        <div class="articleimg">
                           <div class="overlay"></div>
                           <div class="articlecat">
                              <?php foreach((get_the_category()) as $category) { echo $category->cat_name . ' ';}?>
                           </div>
                           <figure>
                              <img src="<?php the_field("featured_image"); ?>" width="330" height="181" alt="<?php the_title(); ?>" title="<?php the_title(); ?>" />
                           </figure>
                        </div>
                        <div class="articlecontent clearfix">
                           <div class="date">
                              <?php echo get_the_date('l, F j, o'); ?>
                           </div>
                           <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                           <div class="articlepreview">
                              <p><?php echo get_excerpt(140); ?></p>
                           </div>
                           <a class="more" href="#">Read More</a>
                        </div>
                     </div>
                  </article>
               </div>
               <?php endwhile; ?>

            <?php endif; wp_reset_postdata(); ?>
            <?php endforeach; ?>
            <?php endif; ?>
         <?php endwhile; endif; ?>


=> NFOrce GIF plugin <= - Ryzen 3800X, 16GB DDR4-3200, Sapphire 5700XT Pulse
Back to top
Interinactive
VIP Member



Posts: 29448

PostPosted: Sun, 21st Dec 2014 10:13    Post subject:
⁢⁢


Last edited by Interinactive on Tue, 5th Oct 2021 01:23; edited 1 time in total
Back to top
dingo_d
VIP Member



Posts: 14555

PostPosted: Sun, 21st Dec 2014 10:42    Post subject:
Did you try putting the '<div class="full clearfix">' before the second loop (foreach)?

When I worked on a 'grid' layout for a theme, we created a $column array and then just counted the posts ($i++ counter), put the html in array $column[$i], and outside of The Loop just outputted the html

<div id="grid_posts" class="clearfix row">
<div class="span4"><?php echo $column[1]; ?></div>
<div class="span4"><?php echo $column[2]; ?></div>
<div class="span4"><?php echo $column[3]; ?></div>
</div>

Full code looks something like this

Code:

<?php if($cat_data['sidebar_position']=='grid'):
            $i = 0;
?>
<?php

$column = array();
$column[1]=$column[2]=$column[3]='';

if (have_posts()) :  while (have_posts()) : the_post();
 
   $i++;

   $column[$i] .= '<html goes here>';
   $column[$i] .= '<more html goes here if you want>';

   $i = ($i==3) ? 0 : $i;
endwhile; ?>
   <div id="grid_posts" class="clearfix row">
      <div class="span4"><?php echo $column[1]; ?></div>
      <div class="span4"><?php echo $column[2]; ?></div>
      <div class="span4"><?php echo $column[3]; ?></div>
   </div>
<?php else: ?>
   <p><?php _e('No posts were found. Sorry!', 'theme'); ?></p>
<?php endif; ?>


"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson
chiv wrote:
thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found.

Back to top
Werelds
Special Little Man



Posts: 15098
Location: 0100111001001100
PostPosted: Mon, 22nd Dec 2014 11:40    Post subject:
I'll rewrite the guide I did for our frontend guys a bit and put it here later, because this is really easy to solve once you know how. Just requires some simple math. It's a little trick I taught most of our guys and they use it all the time now. For dingo_d and pumpy: modulo magic Wink

That code looks fucking horrible though. That is some truly horrendous formatting, what the fuck.


Join in on the war on LeoSatan


Last edited by Werelds on Mon, 22nd Dec 2014 12:28; edited 1 time in total
Back to top
PumpAction
[Schmadmin]



Posts: 26759

PostPosted: Mon, 22nd Dec 2014 12:04    Post subject:
Oops, didn't look close enough that there were three in one. Yes, just requires a bit of module magic. if you haven't figured it out later on, just pm me when you see me on steam, I'll do it in a minute for you Smile


=> NFOrce GIF plugin <= - Ryzen 3800X, 16GB DDR4-3200, Sapphire 5700XT Pulse
Back to top
Interinactive
VIP Member



Posts: 29448

PostPosted: Mon, 22nd Dec 2014 13:06    Post subject:
⁢⁢


Last edited by Interinactive on Tue, 5th Oct 2021 01:23; edited 1 time in total
Back to top
Werelds
Special Little Man



Posts: 15098
Location: 0100111001001100
PostPosted: Mon, 22nd Dec 2014 13:39    Post subject:
This is one of those things where you need to know math, because there is a magical little thing for this called "modulo". That's how the CSS side of it works, so you do already know it...just not in its pure mathematical form. I've taught most of our frontend guys how modulo works and it's become a standard thing they use Wink

So, modulo math. Modulo is done with the percent sign and is much the same as a division; except that what comes out isn't the result of the division, but the remainder. It really is the most basic form in math, you get this in primary school already, just not with the word modulo. So let's take "X / Y" (X divided by Y) and "X % Y" (X modulo Y). With X=3 and Y=2 you get 3/2 = 1.5 and 3%2 = 1. Because when you divide 3 by 2, you're left with 1. 1 is the remainder (the quotient would be 1 too in this case), so that's your answer. Similarly, 5%2 gives you 3. 4%4 gives you 0. Important to note: 0%Y is _always_ 0, since 0 can't be divided, so the remainder is _always_ 0 for 0 modulo <anything>. Or to really put it in primary school terms; when you divide 5 by 2, you can fit the 2 in there 2 times and you're left with 1. Quotient = 2, remainder = 1. We've all done this, it's just that the terms "quotient" and "remainder" along with the operation called "modulo" aren't named as such Razz

While this is easy, the complicated part comes when you apply this in your code. There's a few requirements (all explained inside the example page in comments):
- You have to be counting your stuff in some way
- You have to know your maximum too to avoid ending up with stray tags
- If you're using a 0-based count (like with <?php foreach ($array as $index => $value): ?>), you'll need to "shift" your target remainder by 1

Example page for you guys to drop somewhere and play around with:
Code:

<html>
    <head>
        <style>
            .full {
                width: 960px;
                border: 1px solid red;
                margin: 20px;
            }

            article {
                display: inline-block;
                width: 303px;
                border: 1px solid green;
                margin: 1px;
                padding: 5px;
            }
        </style>
    </head>
    <body>
        <h1>Modulo math example</h1>

        <?php
        // The total number of results we have (usually you'd do like count($array) or something along those lines)
        $total = 21;

        // How many items you want per row
        $divisor = 3;
        ?>

        <h2>"1" based counting</h2>

        <!--
        So even with just 1 item, we still want this to be wrapped in .full, right?

        Problem is that with just 1 item (or any number that isn't a multiple of your divisor),
        "detecting" the last item is nasty, with lots of "ifs".

        So instead, we just _always_ have <div class="full"></div>
        and only close/open new ones inside the loop when necessary.
        -->
        <div class="full">
            <?php
            // Our starting number is 1
            $number = 1;
            ?>
            <?php for ($i = 0; $i < $total; ++$i): ?>
                <!--
                No matter what the divisor is, the first item on a row will always have remainder 1.

                With 3 items per row, your first items will be numbers, 1, 4, 7; 1%3=1, 4%3=1, 7%3=1

                But because we've already opened .full above, we'll skip number 1 here
                -->
                <?php if ($number > 1 && $number % $divisor === 1): ?>
                    <div class="full">
                <?php endif; ?>

                <article>Article here</article>

                <!--
                We want to close .full whenever we're at the end of a row.

                That is always when the remainder is 0; with 3 per row,
                that's numbers 3, 6, 9 - all multiples of 3 and thus %3 = 0.

                Again an exception, the very last element we never want to close,
                again because we've got this global .full around everything.
                So as long as we're not "there" yet and we're at the end of a row, we'll close .full.
                -->
                <?php if ($number < $total && $number % $divisor === 0): ?>
                    </div>
                <?php endif; ?>

                <?php ++$number; ?>
            <?php endfor; ?>
        </div>

        <h2>"0" based</h2>

        <div class="full">
            <!--
            Exact same loop, but no starting number for this one.
            $i is what you'd get when doing foreach ($array as $index => $value)
            -->
            <?php for ($i = 0; $i < $total; ++$i): ?>
                <!--
                Now, there's a slight issue here. Because our count starts at 0, checking for %divisor==1 won't work.
                The first items on each row will be index 0, 3, 6; 0%0 = 0, 3%3 = 0, 6%3 = 0.

                What happens here is that you shifted the targets by 1. So for a target of 3, before you did this:
                1        2        3
                ^full    -        ^close

                Now you want this:
                0        1        2
                ^full    -        ^close

                See what's happened?
                Substracted one on each index; so instead of looking for remainder 1, we're now looking for remainder 0.
                In this case, that works..for the closing tag? See below ;)

                Also, still skipping the very first item of course.
                -->
                <?php if ($i > 0 && $i % $divisor === 0): ?>
                    <div class="full">
                <?php endif; ?>

                <article>Article here</article>

                <!--
                But wait, we were looking for remainder 0 before here, there's no such thing as remainder -1 ?!

                You're right and this is where another math trick comes in, called "shifting".

                Essentially what you're looking for is a value out of an endless list that looks like 0 1 2 0 1 2 0 1 2
                And we basically want the one _before_ index 0; as you can see, that is always 2.
                If you had 5 items per row, that list would be 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 and your target would be 4.

                And because math is so convenient, that just happens to be your divisor, minus one.

                A slight added complication is that obviously our maximum index will always be less than our total (because we started counting at 0, not 1),
                so we need to make sure the index stays not 1, but 2 below the maximum (again, we shifted everything).
                -->
                <?php if ($i < ($total - 1) && $i % $divisor === ($divisor - 1)): ?>
                    </div>
                <?php endif; ?>
            <?php endfor; ?>
        </div>
    </body>
</html>



And for Interinactive, here's his stuff fully worked out. I did fuck with the formatting though, because WP is horrible enough as it is, with their suggested formatting it only gets worse. I did shorten it in some ways though, because some of those lines weren't necessary (like the very first if(have_posts()) already for example; the while condition is the exact same thing, so the if serves no purpose). I kept the flow control blocks on separate lines with their own PHP tags, but blocks with multiple statements I expanded to multiple rows. It's just a terrible idea to do those on a single line, makes them so much harder to read. And I added some comments to explain what's what Razz
Code:

<?php while (have_posts()): ?>
    <?php
    the_post();
    $categories = get_the_terms($post->ID, 'category');
    ?>

    <?php if ($categories && !is_wp_error($categories)): ?>
        <?php foreach ($categories as $category): ?>
            <?php
            $catPosts = new WP_Query(array('category_name' => $category->slug, 'posts_per_page' => -1));

            // Start counting at 1
            // Alternatively, we could skip this and use $current_post inside the loop;
            // which would be a 0-based counter.
            $number = 1;

            // The total number of results we have (usually you'd do like count($array) or something along those lines)
            // Obviously it's also totally pointless to store this in a separate variable (as is $divisor), you can just reference them in the code below.
            // I only did this to keep a clean comparison to the example page above.
            $total = $catPosts->found_posts;

            // How many items you want per row
            $divisor = 3;
            ?>

            <div class="full clearfix">
                <?php while ($catPosts->have_posts()): ?>
                    <?php $catPosts->the_post(); ?>

                    <?php if ($number > 1 && $number % $divisor === 1): ?>
                        <div class="full">
                    <?php endif; ?>

                    <article class="third">
                        <div class="article">
                            <div class="articleimg">
                                <div class="overlay"></div>
                                <div class="articlecat">
                                    <?php foreach ((get_the_category()) as $category) {
                                        echo $category->cat_name . ' ';
                                    } ?>
                                </div>
                                <figure>
                                    <img src="<?php the_field("featured_image"); ?>" width="330" height="181"
                                         alt="<?php the_title(); ?>" title="<?php the_title(); ?>"/>
                                </figure>
                            </div>
                            <div class="articlecontent clearfix">
                                <div class="date">
                                    <?php echo get_the_date('l, F j, o'); ?>
                                </div>
                                <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>

                                <div class="articlepreview">
                                    <p><?php echo get_excerpt(140); ?></p>
                                </div>
                                <a class="more" href="#">Read More</a>
                            </div>
                        </div>
                    </article>

                    <?php if ($number < $total && $number % $divisor === 0): ?>
                        </div>
                    <?php endif; ?>

                    <?php
                    // Increase our post number
                    ++$number;
                    ?>
                <?php endwhile; ?>
            </div>

            <?php
            // This is why you shouldn't have put this on the same line as endwhile.
            // Looks messy and when you need to modify something, you need to split it off to a new line anyway.
            wp_reset_postdata();
            ?>
        <?php endforeach; ?>
    <?php endif; ?>
<?php endwhile; ?>
Back to top
dingo_d
VIP Member



Posts: 14555

PostPosted: Tue, 23rd Dec 2014 20:50    Post subject:
I don't understand, why do you have two divs full (one has clearfix, one doesn't)?

I tried to implement it, and every sixth full had clearfix class. What's the point (especially if you use flexbox)? I mean, clearfix will add pseudoelements that will clear the floats, but why on every sixth element? Or why at all, since full elements will display the articles just fine



"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson
chiv wrote:
thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found.

Back to top
Werelds
Special Little Man



Posts: 15098
Location: 0100111001001100
PostPosted: Tue, 23rd Dec 2014 23:37    Post subject:
Sorry, I forgot to add the clearfix inside the loop, obviously that's meant to have both classes too Smile
Back to top
dingo_d
VIP Member



Posts: 14555

PostPosted: Tue, 23rd Dec 2014 23:40    Post subject:
Oh, ok Smile

It's a neat trick Very Happy


"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson
chiv wrote:
thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found.

Back to top
Interinactive
VIP Member



Posts: 29448

PostPosted: Sat, 27th Dec 2014 01:21    Post subject:
⁢⁢


Last edited by Interinactive on Tue, 5th Oct 2021 01:22; edited 1 time in total
Back to top
dingo_d
VIP Member



Posts: 14555

PostPosted: Sat, 27th Dec 2014 11:13    Post subject:
Code:
 $categories = get_the_terms($post->ID, 'category');
    ?>

    <?php if ($categories && !is_wp_error($categories)): ?>
        <?php foreach ($categories as $category): ?>
         


This is what I'd suspect. You are listing all categories in a foreach loop, and the categories are outputted with get_the_terms, and it could be outputting them in some default category order.


"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson
chiv wrote:
thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found.

Back to top
Interinactive
VIP Member



Posts: 29448

PostPosted: Fri, 20th Feb 2015 03:11    Post subject:
⁢⁢


Last edited by Interinactive on Tue, 5th Oct 2021 01:11; edited 1 time in total
Back to top
LeoNatan
☢ NFOHump Despot ☢



Posts: 73196
Location: Ramat Gan, Israel 🇮🇱
PostPosted: Fri, 20th Feb 2015 10:36    Post subject:
Looks very good! That's Wordpress?
Back to top
LeoNatan
☢ NFOHump Despot ☢



Posts: 73196
Location: Ramat Gan, Israel 🇮🇱
PostPosted: Fri, 20th Feb 2015 10:38    Post subject:
Cataract surgery as a refractive procedure

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tincidunt, leo vel lacinia rutrum, tortor...

Very Happy
Back to top
PumpAction
[Schmadmin]



Posts: 26759

PostPosted: Fri, 20th Feb 2015 11:07    Post subject:
Looks nice inter Smile


=> NFOrce GIF plugin <= - Ryzen 3800X, 16GB DDR4-3200, Sapphire 5700XT Pulse
Back to top
Page 1 of 1 All times are GMT + 1 Hour
NFOHump.com Forum Index - Programmers Corner
Signature/Avatar nuking: none (can be changed in your profile)  


Display posts from previous:   

Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB 2.0.8 © 2001, 2002 phpBB Group