Reputation: 9
I am looping products on my page and the background-color goes as follow:
'transparent' - 'grey' - 'transparent' - 'grey'
There are 4 products on each row but when the second row starts it is doing the same order like:
Situation 1 - Wrong situation
'transparent' - 'grey' - 'transparent' - 'grey'
'transparent' - 'grey' - 'transparent' - 'grey'
But I want it like:
Situation 2 - Correct situation
'transparent' - 'grey' - 'transparent' - 'grey'
'grey' - 'transparent' - 'grey' - 'transparent'
Does anyone know how to edit my loop to get the structure as above?
<div class="row page-margin pb-5">
<?php
$term = get_field('product_category'); if( $term ): $cat = esc_html( $term->slug ); endif;
$args = array( 'post_type' => 'product', 'product_cat' => $cat);
$loop = new WP_Query( $args );
$product_id = get_the_id();
$c = 0;
$product = wc_get_product( $product_id );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<div class="col-md-3 pl-0 pr-0">
<a href="<?php the_permalink(); ?>">
<div class="product-list-item <?php if ($c & 1) { ?>bg-grey<?php } ?>">
<div class="img-wrapper">
<?php echo $product->get_image('full', array('class' => 'img-fluid')); ?>
</div>
<div class="product-content">
<span class="product-title"><?php echo $product->get_name(); ?></span>
<span class="product-price">€ <?php $price = $product->price; $price_incl_tax = $price + round($price * ( 0 / 100 ), 2); $price_incl_tax = number_format($price_incl_tax, 2, ",", "."); $price = number_format($price, 2, ",", "."); echo $price_incl_tax; ?> incl. BTW</span>
</div>
</div>
</a>
</div>
<?php $c++; endwhile; wp_reset_query(); // Remember to reset ?>
</div>
Here is an image of the wrong situation (Situation 1):
Wrong situation picture
Thanks for your time!
Upvotes: 0
Views: 177
Reputation: 2929
No need to hardcode this into your template. Use CSS to achieve this with a slightly complex list of selectors. You can wrap this in a media query since I see you have col-md-3
. Assuming you're using bootstrap, that would be @include media-breakpoint-up(md)
you'd be using.
.container {
display: flex;
flex-wrap: wrap;
background: gray;
}
.item {
display: flex;
justify-content: center;
align-items: center;
width: 25%;
height: 100px;
background: white;
}
.item:nth-child(4n+2):not(:nth-child(8n-2)), /* 2, 10, 18… */
.item:nth-child(4n+4):not(:nth-child(8n)), /* 4, 12, 20… */
.item:nth-child(4n+1):not(:nth-child(8n+1)), /* 5, 13, 21… */
.item:nth-child(4n+3):not(:nth-child(8n+3)) { /* 7, 15, 23… */
background: red;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
<div class="item">17</div>
<div class="item">18</div>
<div class="item">19</div>
<div class="item">20</div>
</div>
Now to explain the selector logic: you want to target every 2nd and 4th child on odd rows, and the 1st and 3rd child on even rows. To do so, you target, respectively:
Hope this helps!
Upvotes: 1
Reputation: 23958
If you want it done in php the method I found working is to use two arrays which is out of sync with transparent and grey.
Then echo from one array on one row then switch.
It's not a nice code but it does the trick.
$arr1 = ['transparent', 'grey', 'transparent', 'grey'];
$arr2 = ['grey', 'transparent', 'grey', 'transparent'];
$i = 0;
$bool = true;
Your loop{
if($bool){
echo 'color ' . $arr1[$i] . "\n";
}else{
echo 'color ' . $arr2[$i] . "\n";
}
$i = ++$i % 4;
if($i ==0) $bool = !$bool;
}
Here is a running example of the code:
Upvotes: 0
Reputation: 17805
Ok this is a little tricky because you are changing the order of decision at the chunk of 4.
To decide this, you can have an extra $flag
variable which is initially set to false
.
So, the check goes as:
if ($flag && ($c & 1) == 0 || !$flag && ($c & 1) == 1)
This says if we are at the odd iteration(when $flag is false) and current $c
is odd or we at the even iteration(when $flag is true) and current $c
is even.
We reset the flag when $c
gets reinitialized to 0
indicating next row flip.
Snippet:
<?php
$c = 0;
$product = wc_get_product( $product_id );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<div class="col-md-3 pl-0 pr-0">
<a href="<?php the_permalink(); ?>">
<div class="product-list-item <?php if ($flag && ($c & 1) == 0 || !$flag && ($c & 1) == 1) { ?>bg-grey<?php } ?>">
<div class="img-wrapper">
<?php echo $product->get_image('full', array('class' => 'img-fluid')); ?>
</div>
<div class="product-content">
<span class="product-title"><?php echo $product->get_name(); ?></span>
<span class="product-price">€ <?php $price = $product->price; $price_incl_tax = $price + round($price * ( 0 / 100 ), 2); $price_incl_tax = number_format($price_incl_tax, 2, ",", "."); $price = number_format($price, 2, ",", "."); echo $price_incl_tax; ?> incl. BTW</span>
</div>
</div>
</a>
</div>
<?php $c = ($c + 1) % 4; $flag = $c == 0 ? !$flag : $flag; endwhile; wp_reset_query(); // Remember to reset ?>
Upvotes: 0