Bootstrap grid in loop - php

I am trying to make something like the image.
I'm using WordPress and woocommerce and would like to display products like this.
This is the normal html that does the work.
I need to be able to put it into a loop:
<div class="container" style="width: 100%">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3">Span 3</div>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3">
<div>Span 2</div>
<div>Span 2</div>
<div>Span 2</div>
</div>
</div>
</div>
I am using the bootstrap grid.css
Here is what I have done:
while ($loop->have_posts()) : $loop->the_post();
if ($product_counter < $product_counter_max) {
if ($grid_counter == 0) { ?>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3">
<img src="<?php echo get_the_post_thumbnail_url($loop->post->ID); ?>"/>
<?php echo get_the_title();
$product = wc_get_product($loop->post->ID);
/**reviews**/
$average = $product->get_average_rating($loop->post->ID);
$review_count = $product->get_review_count($loop->post->ID);
if ($average != 0) {
for ($x = 0; $x < 5; $x++) {
if ($x < $average) {
echo '<i class="fa fa-star swatchchecked"></i>';
} else {
echo '<i class="fa fa-star"></i>';
}
}//for loop
}//end of if
else {
echo "No Rating Yet";
}//end of reviews
echo '<p>' . sprintf("%.2f", $product->get_price()) . '</p>';
?>
</div>
<?php
} else {
?>
<div style="clear: both">there</div>
<?php
}
}
$grid_counter++;
$product_counter++;
endwhile;
} else {
echo __('No products found');
}
wp_reset_postdata();
I'm not sure how to make the little items stack 3 on top of each other like the image
Please help!

So here's a way to create the grid layout you want. While the minute details aren't included in this answer, what I'm providing for you should give you enough of an idea of how to set up the inner portions to layout how you want those to layout.
If it was me... I'd set it up so that with your incremented grid, you can make different layouts for the columns 1 and 3 vs column 2 and 4. But like I said, this should point you in the right direction.
// Not sure why you are using a counter value when you can
// set the loop to return whatever you want. But you didn't show your loop
$product_counter_max = 8;
// Set grid counter at 1;
$grid_counter = 1;
$product_counter = 0;
echo '<div class="row">';
if ($loop->have_posts()){
while ($loop->have_posts()) : $loop->the_post();
// This next line could be superflous based on earlier comment
if ($product_counter < $product_counter_max) {
if ($grid_counter == 1 || $grid_counter == 5 ) {
echo '<div class="col-3">';
} else {
// Add an extra wrapper div around the second and fourth column
if ($grid_counter == 2 || $grid_counter == 6 ) echo '<div class="col-3">';
// This is an inner column
echo '<div class="col-12">';
}?>
<img src="<?php echo get_the_post_thumbnail_url($loop->post->ID); ?>"/>
<?php echo get_the_title();
$product = wc_get_product($loop->post->ID);
/**reviews**/
$average = $product->get_average_rating($loop->post->ID);
$review_count = $product->get_review_count($loop->post->ID);
if ($average != 0) {
for ($x = 0; $x < 5; $x++) {
if ($x < $average) {
echo '<i class="fa fa-star swatchchecked"></i>';
} else {
echo '<i class="fa fa-star"></i>';
}
}//for loop
}//end of if
else {
echo "No Rating Yet";
}//end of reviews
echo '<p>' . sprintf("%.2f", $product->get_price()) . '</p>';
?>
</div>
<?php
if ($grid_counter == 4 || $grid_counter == 8 ) echo '</div>';
}
$grid_counter++;
$product_counter++;
endwhile;
} else {
echo __('No products found');
}
wp_reset_postdata();
echo '</div>';

Related

PHP - Adding 2 div to a foreach loop every 4 times with ACF Repeater

I have an ACF Repeater field i'd like to output as an accordion grid, like so:
<div class="intro row">
<div class="item item-1">name 1</div>
<div class="item item-2">name 2</div>
<div class="item item-3">name 3</div>
<div class="item item-4">name 4</div>
</div>
<div class="expanded row">
<div class="expand" id="item-1">expanded info 1</div>
<div class="expand" id="item-2">expanded info 2</div>
<div class="expand" id="item-3">expanded info 3</div>
<div class="expand" id="item-4">expanded info 4</div>
</div>
<div class="intro row">
<div class="item item-5">name 5</div>
<div class="item item-6">name 6</div>
<div class="item item-7">name 7</div>
<div class="item item-8">name 8</div>
</div>
<div class="expanded row">
<div class="expand" id="item-5">expanded info 5</div>
<div class="expand" id="item-6">expanded info 6</div>
<div class="expand" id="item-7">expanded info 7</div>
<div class="expand" id="item-8">expanded info 8</div>
</div>
I can group the initial row fine, it's just the second "expanded" row i'm having trouble with. How can I repeat and group the second row of 4 correctly in the same loop? My current PHP:
<?php // check if the repeater field has rows of data
if( have_rows('features') ):
// loop through the rows of data
// add a counter
$count = 0;
$group = 0;
while ( have_rows('features') ) : the_row();
$name = get_sub_field('feature_name');
$expandedInfo = get_sub_field('feature_info');
if ($count % 4 == 0) {
$group++;
?>
<div class="intro row">
<?php
}
?>
<div class="item item-<?php echo $count; ?>">
<?php echo $name ?>
</div><!-- item-->
<?php
if ($count % 4 == 3) {
?>
</div><!-- intro-->
<?php
}
$count++;
endwhile;
else :
// no rows found
endif;
?>
The second 'expanded' row can be done so that you store each count (item-1,item-2) in an array or just traverse through all the count when you close the intro row.
<?php
if ($count % 4 == 3) {
?>
</div><!-- intro-->
<div class="expanded row">
<?php
$start = $count-3;
// if $count is 4, $start will be 1, and the $i will go to 4
// if $count is 8, $start will be 5
for($i=$start;$i<=$count;$i++){
echo '<div class="expand" id="item-' . $i . '"></div>';
} ?>
</div>
<?php
}
This is just an example. I would suggest you to store each $count in an array and then use the count($array) to get the number of them. After you have traversed the array, reset it.
The Array Approach
<?php // check if the repeater field has rows of data
if( have_rows('features') ):
// loop through the rows of data
// add a counter
$count = 0;
$group = 0;
// Content Array
$content_array = array();
while ( have_rows('features') ) : the_row();
$name = get_sub_field('feature_name');
$expandedInfo = get_sub_field('feature_info');
// Adding the Expanded Info
$content_array[ 'item-' . $count ] = $expandedInfo;
if ($count % 4 == 0) {
$group++;
?>
<div class="intro row">
<?php
}
?>
<div class="item item-<?php echo $count; ?>">
<?php echo $name ?>
</div><!-- item-->
<?php
if ($count % 4 == 3) {
?>
</div><!-- intro-->
<div class="expanded row">
<?php
foreach( $content_array as $item_id => $expanded_info ) {
echo '<div class="expanded" id="' . $item_id . '">';
echo $expanded_info;
echo '</div>';
} ?>
</div>
<?php
// Resetting the Array
$content_array = array();
}
$count++;
endwhile;
else :
// no rows found
endif;
?>
okey, lets see ,
using variables to store your templates may helps a lot in this context ,
as follow :
$intro = '';
$expanded = '';
while (have_rows('features')) :
the_row();
if ($count % 4 == 0) {
$group++;
$intro .= '<div class="intro row">';
$expanded .= '<div class="expanded row">';
}
$intro .= '<div class="item item-' . $count . '"></div><!-- item-->';
$expanded .= '<div class="expand" id="item-' . $count . '"></div>';
if ($count % 4 == 3) {
$intro = '</div><!-- intro-->';
$expanded = '</div><!-- intro-->';
}
$count++;
endwhile;
I've made a quick example to explain to show you how using variables may fix your issue : https://3v4l.org/cKPP4
Can't test it right now, but I think something like that should work.
<?php // check if the repeater field has rows of data
if( have_rows('features') ):
// loop through the rows of data
// add a counter
$count = 0;
$group = 0;
$array = array();
while ( have_rows('features') ) : the_row();
$name = get_sub_field('feature_name');
$expandedInfo = get_sub_field('feature_info');
if ($count % 4 == 0) {
$group++;
?>
<div class="intro row">
<?php
}
?>
<div class="item item-<?php echo $count; ?>">
<?php echo $name ?>
</div><!-- item-->
<?php
array_push($array, $expandedInfo);
if ($count % 4 == 3) {
?>
</div><!-- intro-->
<div class="expanded row">
<?php
for ($i=0; $i < count($array); $i++) {
echo '<div class="expand" id="item-'.$i + 1.'">'.$array[$i].'</div>';
}
echo '</div>';
}
$count++;
endwhile;
else :
// no rows found
endif;
?>

PHP loop rating bar error

I have a 5 point rating system I am trying to change up how it displays the rating.
So before it would be 5 dots all white if not rated, then color in the ratings blue.. I would display these dots via fontawesome glyphs. So it would output 5 of them.
But now i'm trying to change it where the 5 point rating would display a progress bar and the 5 points be used as percentages for the length of progress.
Sorry if i am vague, I can explain more if needed. It currently displays all the bars and rating values, but just once. So it's not functioning the way I want it to.
<?php if(count($languages) > 0) { ?>
<div class="col-md-6">
<ul class="no-bullets">
<?php foreach($languages as $index => $language) { ?>
<li>
<span class="skillset-title"><?= $language->title; ?> (<?= $language->endorsement; ?>)</span>
<span class="skillset-rating">
<?php
$levelpercentage = 0;
for($stars == 1; $stars <= 5; $stars++) {
if ($stars == 5):
echo $levelpercentage = 100;
elseif ($stars == 4):
echo $levelpercentage = 80;
elseif ($stars == 3):
echo $levelpercentage = 60;
elseif ($stars == 2):
echo $levelpercentage = 40;
elseif ($stars == 1):
echo $levelpercentage = 20;
endif;
?>
<div class="progress-bar blue stripes">
<span style="width: <?= ($language->level >= $stars) ? $levelpercentage : '0'; ?>%;"></span>
</div>
<?php } ?>
</span>
</li>
<?php if(ceil(count($languages) / 2) == $index + 1) { ?>
</ul>
</div>
<div class="col-md-6">
<ul class="no-bullets">
<?php } ?>
<?php } ?>
</ul>
</div>
<?php } else { ?>
<div class="alert alert-warning">
No languages were found!
</div>
<?php } ?>
It currently displays all the bars and rating values
That's because you assign and echo your bars and rating values in a for loop.
Your $stars variable is assigned every value from 1 to 5, displaying the bar at each step. Simply remove your for loop and it should work fine (provided you use an already defined $stars variable)
Bonus : Because I'm in a good mood, I have to tell you there's a simpler way to build your $levelpercentage variable than using an if...else for each value from 1 to 5, just use :
$levelpercentage = $stars * 20;
Thank you! That really helped me out. Was trying to simplify what I was trying to do. This is what I did and it seems to be working.
<?php if(count($languages) > 0) { ?>
<div class="col-md-6">
<ul class="no-bullets">
<?php foreach($languages as $index => $language) { $stars = 0; $stars <= 5; $stars++; ?>
<li>
<span class="skillset-title"><?= $language->title; ?> (<?= $language->endorsement; ?>)</span>
<span class="skillset-rating">
<div class="progress-bar blue stripes">
<span style="width: <?= ($language->level >= $stars) ? $language->level * 20 : 0; ?>%;"></span>
</div>
</span>
</li>
<?php if(ceil(count($languages) / 2) == $index + 1) { ?>
</ul>
</div>
<div class="col-md-6">
<ul class="no-bullets">
<?php } ?>
<?php } ?>
</ul>
</div>
<?php } else { ?>
<div class="alert alert-warning">
No languages were found!
</div>
<?php } ?>

Php foreach loop wrapped every 2items with a row

<div class="puffar">
<?php
//Set up the objects needed
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page'));
//Get children
$children = ($post->post_parent) ? get_page_children($post->post_parent, $all_wp_pages) : get_page_children($post->ID, $all_wp_pages);
$i = 0;
//Build custom items
echo "<div class='row'>";
foreach ($children as $child) {
?>
<div class="col-sm-6">
<div class="puff">
<div class="puff-image-holder">
<?php echo get_the_post_thumbnail($child->ID, 'full'); ?>
</div>
<fieldset class="linedHeadline hlmedium">
<legend><?php echo get_the_title($child->ID); ?></legend>
</fieldset>
<?php echo get_field("puff_introtext", $child->ID); ?>
<?php
$values = get_field('puff_lanktext', $child->ID);
if (get_field("popup_eller_lank", $child->ID) == "popup") {
?>
<fieldset class="linedHeadline hlmedium">
<legend><a class="linktopage open-popup"
href="<?php echo get_page_link($child->ID); ?>"><?php echo get_field("puff_lanktext", $child->ID); ?> </a>
</legend>
</fieldset>
<?php
} elseif (get_field("popup_eller_lank", $child->ID) == "extern") {
?>
<fieldset class="linedHeadline hlmedium">
<legend><a class="linktopage"
href="<?php echo get_field("puff_lank", $child->ID); ?>"><?php echo get_field("puff_lanktext", $child->ID); ?> </a>
</legend>
<?php
$i++;
if ($i % 2 == 0) {
echo "</div><div class='row'>";
}
} else {
}
?>
</div>
</div>
<?php } ?>
</div>
</div>
I want every 2 items that's rendered out to be wrapped in a <div class="row">, however I can't figure it out. Can anyone help me?
So basically the row should wrap every 2 elements that is getting looped. I have been stuck on this forever... Hopefully anyone got better expertise than me hehe.
The div="row" should wrap the col-sm-6 and class="puff".
$i = 0;
foreach ($children as $child) {
$i++;
// your code goes here
if($i % 2 == 0) {
echo "</div><div class='row'>";
// reset the counter to 0
$i = 0 ;
}
}
use proper logic
if ($i % 2 == 0) {
echo "</div><div class='row'>";
}
$i++;
First check if its mod by 2 or not (Gives 0 value after MOD), then close div , open new.
Now increase counter . Because for the first time , i will be 0 , then you increment it and then you use logic. So in short counter shoul be incremented at the end only not in between before you do any operation/logic.
Updated
Use code as it is **: issue was you have i++ and your condition in 3rd else if which never executed. So took it outside All and just before foreach.
<div class="puffar">
<?php
//Set up the objects needed
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page'));
//Get children
$children = ($post->post_parent) ? get_page_children($post->post_parent, $all_wp_pages) : get_page_children($post->ID, $all_wp_pages);
$i = 0;
//Build custom items
echo "<div class='row'>";
foreach ($children as $child) {
?>
<div class="col-sm-6">
<div class="puff">
<div class="puff-image-holder">
<?php echo get_the_post_thumbnail($child->ID, 'full'); ?>
</div>
<fieldset class="linedHeadline hlmedium">
<legend><?php echo get_the_title($child->ID); ?></legend>
</fieldset>
<?php echo get_field("puff_introtext", $child->ID); ?>
<?php
$values = get_field('puff_lanktext', $child->ID);
if (get_field("popup_eller_lank", $child->ID) == "popup") {
?>
<fieldset class="linedHeadline hlmedium">
<legend><a class="linktopage open-popup"
href="<?php echo get_page_link($child->ID); ?>"><?php echo get_field("puff_lanktext", $child->ID); ?> </a>
</legend>
</fieldset>
<?php
} elseif (get_field("popup_eller_lank", $child->ID) == "extern") {
?>
<fieldset class="linedHeadline hlmedium">
<legend><a class="linktopage"
href="<?php echo get_field("puff_lank", $child->ID); ?>"><?php echo get_field("puff_lanktext", $child->ID); ?> </a>
</legend>
<?php
} else {
}
?>
</div>
</div>
<?php
if ($i % 2 == 0) {
echo "</div><div class='row'>";
}
$i++;
} ?>
</div>
</div>
First set $i=0;
if ($i % 2 == 0) {
echo "</div><div class='row'>";
}
$i++;

Iterating over 12 items specify markup up on nth items

Hi I am using Bootstrap 2 with a PHP content management system.
I am rendering 12 items from the database, each 3 items needs to be wrapped in a row. However I am unable to achieve this my last attempt is below (with simplified markup):
$i = 1;
echo "<div class='row-fluid'>";
foreach($posts as $p) {
if ($i % 3 == 0) {
echo "</div>";
}
if ($i % 4 == 0) {
echo "<div class='row-fluid'>";
}
echo "<div class='span4'><h5>$p->title</h5></div>";
$i++;
}
In affect what I am looking for is something like this:
<div class="row">
<div class="item></item>
<div class="item"</item>
<div class="item"></item>
</div>
<div class="row">
<div class="item></item>
<div class="item"</item>
<div class="item"></item>
</div>
<div class="row">
<div class="item></item>
<div class="item"</item>
<div class="item"></item>
</div>
<div class="row">
<div class="item></item>
<div class="item"</item>
<div class="item"></item>
</div>
I have tried everything I can think of any help would be great thanks.
Try if there are 12 rows :
echo "<div class='row-fluid'>";
foreach($posts as $p) {
echo "<div class='span4'><h5>$p->title</h5></div>";
if ($i % 3 == 0) {
echo "</div>";
echo ( $i< 12 )? "<div class='row-fluid'>" : "";
}
$i++;
}
I think this will work
$i = 0;
echo "<div class='row-fluid'>";
foreach($posts as $p) {
echo "<div class='span4'><h5>$p->title</h5></div>";
if ($i % 3 == 0) {
echo "</div><div class='row-fluid'>";
}
$i++;
}
echo "</div>";

PHP loop modulo

I would like to make this in a loop:
<div class="global">
<div class="left">1</div>
<div class="right">2</div>
</div>
<div class="global">
<div class="left">3</div>
<div class="right">4</div>
</div>
<div class="global">
<div class="left">5</div>
<div class="right">6</div>
</div>
<div class="global">
<div class="left">7</div>
<div class="right">8</div>
</div>
<div class="global">
<div class="left">9</div>
<div class="right">10</div>
</div>
I know do something link this :
for($i=0;$i<4;$i++){
if($i %2){
$classe='class="right"';
}
else{
$classe='class="left"';
}
echo "<div ".$classe." >".$i."</div>";
}
which result:
<div class="left">1</div>
<div class="right">2</div>
<div class="left">3</div>
<div class="right">4</div>
How Can I integrate the div "global" between ?
Thanks a lot for your help
Iterate two by two:
for ($i = 1; $i <= 4; $i += 2) {
echo '<div class="global">';
echo '<div class="left">' . $i . '</div>'
echo '<div class="right">' . ($i+1) . '</div>'
echo '</div>';
}
You just need a little extra...
echo '<div class="global">'; //start the first global div
for($i=0;$i<4;$i++){
if($i %2){
$classe='class="right"';
}
else{
$classe='class="left"';
}
echo "<div ".$classe." >".$i."</div>";
if($i %2)
{
//after each "right" div, close and open a new global div
echo "</div>\n<div class=\"global\">";
}
}
echo '</div>'; //close the final global div
You can also compact the whole thing a bit:
echo '<div class="global">'; //start the first div
for($i=0;$i<4;$i++)
{
if($i %2)
{
echo "<div class=\"right\" >$i</div>\n</div>\n<div class=\"global\">";
}
else
{
echo "<div class=\"right\" >$i</div>";
}
}
echo '</div>'; //close the final global div
I like printf.
$i=1;
while ($i < 8) {
printf('<div class="global"><div class="left">%d</div><div class="right">%d</div></div>', $i++, $i++);
}
Edit:
Although this doesn't really answer the OP question, and none of the other answers (yet) use modulus as per the question title. So, here is another far more ugly way :)
echo '<div class="global">';
for($i=0;$i<8;$i++){
if ($i %2) {
$classe='right';
$sep='</div><div class="global">';
}
else{
$classe='left';
$sep='';
}
printf('<div class="%s">%d</div>%s', $classe, $i+1, $i<7?$sep:'');
}
echo '</div>';
This code works :
echo '<div class="global">'; //start the first global div
for($i=0;$i<7;$i++){
if($i %2){
$classe='class="right"';
}
else{
$classe='class="left"';
}
echo "<div ".$classe." >".$i."</div>";
if($i %2)
{
//after each "right" div, close and open a new global div
echo "</div>\n<div class=\"global\">";
}
}
echo '</div>';

Categories