Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop php with multiple styling div

I am working on a WP theme and stumbled into a specific task which I can't describe here but I am sure if I show some screenshots here then you can understand the issue.

First of all please see the below image for posts div structure

enter image description here

It is the actual design from HTML, and specifically the first 2 posts inside a div and the third post inside another div like the below screenshot

enter image description here

please put a comment if you can't understand this.

The question is how to loop that dynamically by keeping the same structure and design?

And here is my codes below

<div class="row justify-content-center">
    <div class="col-xl-3 col-lg-6 col-md-6">
        <?php
        while($projects_array->have_posts()):
            $projects_array->the_post();

            $idd = get_the_ID();
            $terms = wp_get_post_terms(get_the_ID(), 'project_cat');

            $output = array();
            if ($terms) {
                $i = 1;
                foreach ($terms as $term) {
                    if($i == 1):
                        $output[] = '<span class="tag-'.$i.'">'.$term->name.'</span>';
                        $id[] = $term->term_id ;
                    endif;
                    $i++;
                }
            }

            if ( class_exists('ACF') && get_field('choose_link_type') == 1 ) {
                $post_link = get_the_permalink();
            } else {
                $post_link = get_field('external_link');
            }
            ?>
                <div class="single-portfolio-box">
                    <?php if(has_post_thumbnail()): ?>
                        <img src="<?php the_post_thumbnail_url(); ?>" alt="<?php the_post_thumbnail_caption(); ?>">
                    <?php endif; ?>
                    <div class="content">
                        <h3><a href="<?php echo esc_url( $post_link ); ?>"><?php the_title(); ?></a></h3>
                        <?php echo join( ' ', $output ); ?>
                    </div>
                </div>
        <?php endwhile; ?>
        <?php wp_reset_query(); ?>
    </div>
</div>

Thanks in advance.

like image 353
jesica Avatar asked Sep 14 '21 09:09

jesica


2 Answers

You can create an index and perform the output in three different cases, like this:

$index = 1;
while ($projects_array->have_posts()) {
    $modulo3 = $index % 3;
    //Initialize your values
    if (($modulo3 === 1) || ($modulo3 === 0)) {
        //Display the wrapper div's start
    }
    //Display the actual post content
    if (($modulo3 % 3 === 2) || ($modulo3 === 0)) {
        //Display the wrapper div's end
    }
    $index++;
}
if ($index % 3 === 2) {
    //Display the wrapper div's end
}

I did not delve into your structure, since you know that better than me. However, the idea is that if you have a numeric value that indicates your current status, then you know what part of the wrapper needs to be displayed. Each cycle of 3 iterations consists of:

  • step 1: display the wrapper's start and the post
  • step 2: display the post and the wrapper's end
  • step 3: display the wrapper's start, the post and the wrapper's end

So far, so good. If the number of iterations is a multiple of 3, then you will have on each step two posts wrapped into a wrapper and a third one wrapped into a wrapper. However, if the number of posts is not a multiple of three, then you will have a special case in the last group of three that you will need to handle. If the number of posts to display is 3n + 2 where n is a natural number, then your last group will consist of two posts, which will be wrapped nicely by a wrapper inside the cycle. However, if the number of posts to display is 3n + 1, where n is a natural number, then at your very last step you opened the wrapper and displayed a post. In that case, you will need to close the wrapper just after the cycle.

like image 50
Lajos Arpad Avatar answered Oct 17 '22 04:10

Lajos Arpad


I use $post_index to handle which index we will open and close div. So basically, We will:

  • open div at 1, 3, 4, 6, 7, 9...
  • close div at 2, 3, 5, 6, 8, 9...

We handle this by $post_index % 3. So the translated condition is:

  • open div condition: $post_index % 3 == 1 || $post_index % 3 == 0
  • close div condition: $post_index % 3 == 2 || $post_index % 3 == 0

And I use $is_open to tracking open div status to handle if the div is open, and it's not closed because the post length is not enough to match close condition. In that case, we will close it manually.

<div class="row justify-content-center">

        <?php
        $post_index = 0;
        $is_open = false;
        while($projects_array->have_posts()):

            $post_index++;
            // open div to wrap posts by grouped 1, 3, 4, 6, 7, 9...
            if ($post_index % 3 == 1 || $post_index % 3 == 0) {
                echo '<div class="col-xl-3 col-lg-6 col-md-6">';
                $is_open = true;
            }

            $projects_array->the_post();

            $idd = get_the_ID();
            $terms = wp_get_post_terms(get_the_ID(), 'project_cat');

            $output = array();
            if ($terms) {
                $i = 1;
                foreach ($terms as $term) {
                    if($i == 1):
                        $output[] = '<span class="tag-'.$i.'">'.$term->name.'</span>';
                        $id[] = $term->term_id ;
                    endif;
                    $i++;
                }
            }

            if ( class_exists('ACF') && get_field('choose_link_type') == 1 ) {
                $post_link = get_the_permalink();
            } else {
                $post_link = get_field('external_link');
            }
            ?>
            <div class="single-portfolio-box">
                <?php if(has_post_thumbnail()): ?>
                    <img src="<?php the_post_thumbnail_url(); ?>" alt="<?php the_post_thumbnail_caption(); ?>">
                <?php endif; ?>
                <div class="content">
                    <h3><a href="<?php echo esc_url( $post_link ); ?>"><?php the_title(); ?></a></h3>
                    <?php echo join( ' ', $output ); ?>
                </div>
            </div>

            <?php
                // close wrapped div if post index is 2, 3, 5, 6, 8, 9...
                if ($post_index % 3 == 2 || $post_index % 3 == 0) {
                    $is_open = false;
                    echo '</div>';
                }
            ?>

        <?php endwhile; ?>
        <?php wp_reset_query(); ?>

    <?php
        // close div if it's closed (happens when post count is 1, 4, 7,...)
        if ($is_open) {
            echo '</div>';
        }
    ?>

</div>

I ran it on my own site and it works perfectly. Demo HTML structure

like image 39
Tartarus Avatar answered Oct 17 '22 02:10

Tartarus