I need to create a loop like this via PHP ( a WordPress WP_Query ) ,
it's like one large item then two small items and then two small items again , and then , one large item and so on...
Here's the plain HTML :
<div class="swiper-slide big">
<div class="item"></div>
</div>
<div class="swiper-slide normal">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="swiper-slide normal">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="swiper-slide big">
<div class="item"></div>
</div>
<div class="swiper-slide normal">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="swiper-slide normal">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="swiper-slide big">
<div class="item"></div>
</div>
The <div.item>s are post elements.
I couldn't find any pattern to make such loop , one option is to use a counter and compare each number , but it's not a stable way to do this.
could anyone help please.
f.n : the .swiper-slide DIVs are just wrappers , every time the loop runs , we only have a <div.item> and we need to group these .items with the pattern i explained above.
Instead of using a "counter", you could use a modulo equation.
In your example, there are 3 rules we can apply:
One big, then four small
The first and third small start a new parent div
The second and fourth small end the parent div
Assuming that your posts are in an array, with numbered keys, you can use this:
foreach ($itemArray as $key => $item) {
$modulo = ($key+1)%5;
switch($modulo) {
case 1:
echo <<<END
<div class="swiper-slide big">
<div class="item"></div>
</div>
END;
break;
case 2:
case 4:
echo <<<END
<div class="swiper-slide normal">
<div class="item"></div>
END;
break;
case 3:
case 0:
echo <<<END
<div class="item"></div>
</div>
END;
break;
}
}
//Closing possible open div
$arrCountModulo=count($itemArray)%5;
if($arrCountModulo==2||$arrCountModulo==4) {
echo "</div>";
}
Here is an updated example where you pass the items as an array :
<?php
function myloop($items) {
$i = 0;
$isBig = array( true, false, false);
while(sizeof($items) > 0) {
if($isBig[$i]) {
echo "Big ! ", array_shift($items);
echo " \n";
} else {
echo "Normal... ", array_shift($items), " ", array_shift($items);
echo " \n";
}
$i = ( $i + 1) % sizeof($isBig);
}
}
myloop(array("item1","item2","item3","item4","item5","item6","item7","item8","item9","item10"));
?>
Cli output :
$ php loop.php
Big ! item1
Normal... item2 item3
Normal... item4 item5
Big ! item6
Normal... item7 item8
Normal... item9 item10
Use a counter variable(for this example, $i) to track how many div sections are printed. Your code should be like this:
Edited:
Based on your requirement, I've updated my answer.
$itemArray = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q");
$arrLength = count($itemArray);
for($i = 0; $i < $arrLength; ++$i){
if($i % 3 == 0){
if($i != 0){
?>
</div>
<?php
}
?>
<div class="swiper-slide big">
<div class="item"><?php echo $itemArray[$i]; ?></div>
</div>
<div class="swiper-slide normal">
<?php
}else{
?>
<div class="item"><?php echo $itemArray[$i]; ?></div>
<?php
}
}
Try this:
$bignormal = 0;
for ($i=0;$i<$whatever;$i++) {
if ($bignormal>0) {
echo "normal";
}
else {
echo "big";
}
$bignormal++;
if ($bignormal>2) {
$bignormal = 0;
}
}
Not the greatest piece of code in the world, but it works.
Explaination:
$bignormal is (by default) set to 0. $bignormal is thus not greater than 0, so we echo big and increment $bignormal.
Next iteration, $bignormal is 1, thus being greater than 0 so we echo normal and increment $bignormal.
Next iteration, $bignormal is 2, and thus is greater than 0 so we echo normal. However, when we increment $bignormal it is now greater than 2 (with a value of 3), so the final if statement sets $bignormal to 0.
Next iteration $bignormal is set to 0, so thus it's not greater than 0, so thus we echo big and increment $bignormal yet again.
Etc.
In conclusion...
Nothing that complicated, and could probably be compacted down heaps with some better logic :D
Related
I have an array with items: $array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7']
I am looking for the following HTML:
<div class="big">Item 1</div>
<div>
<div class="small">Item 2</div>
<div class="small">Item 3</div>
</div>
<div class="big">Item 4</div>
<div>
<div class="small">Item 5</div>
<div class="small">Item 6</div>
</div>
<div class="big">Item 7</div>
In text: Every 3rd item (including the first) have to have their own div, while the 2nd and 3rd items get a wrapping div.
I've come up with the following loop, but I'm pretty sure it's not going to work in the long run, since it'll probably end the loop with an opening div, since I keep on opening a new one after each BIG ITEM.
$i = 0;
foreach($array as $item) {
<?php
if($i % 3 == 0) {
if($i == 0) {?>
<div class="big">
Item <?= $i; ?>
</div>
<div>
<?php } else { ?>
</div>
<div class="big">
Item <?= $i; ?>
</div>
<div>
<?php } ?>
<?php } else { ?>
<div class="small">
small item
<?= $i; ?>
</div>
<?php } ?>
<?php
$i++;
}
I feel like I'm close, but it also feels wrong to start and close divs in $is where it doesn't belong. Maybe the only thing I'm missing is checking if $i equals the length of the array, and then don't open a new <div> after a big item?
You can use simple if-elseif-else construct to print the divs.
If the index of the current element % 3 is 0, it is a big div, else it is a small div.
If the index of the current element % 3 is greater than 0, it is a small div.
If it is 1, prepend an opening div tag.
If it is 2, append a closing div tag.
Snippet:
<?php
foreach ($array as $idx => $set) {
$mod = $idx % 3;
if($mod === 0){
echo "<div class='big'>$set</div>";
}elseif($mod === 1){
echo "<div><div class='small'>$set</div>";
}else{// if $mod is 2
echo "<div class='small'>$set</div></div>";
}
}
Online Demo
Alternatively, use array_chunk then pick out the first item with array_shift, then join the remaining.
<?php
$array = array_chunk(['item 1','item 2','item 3','item 4','item 5','item 6','item 7'], 3);
foreach ($array as $set) {
echo '<div class="big">'.array_shift($set).'</div>';
if (count($set)) echo '<div><div class="small">'.implode('</div><div class="small">', $set).'</div></div>';
}
?>
Result
<div class="big">item 1</div>
<div>
<div class="small">item 2</div>
<div class="small">item 3</div>
</div>
<div class="big">item 4</div>
<div>
<div class="small">item 5</div>
<div class="small">item 6</div>
</div>
<div class="big">item 7</div>
Example: https://3v4l.org/URB3D
Here you are my simple answer: I think you don't need to use additional counter in case that interpreter adds indexes to array:
$array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7'];
foreach($array as $key=>$da){
$a = $key % 3;
if($a === 0){
echo "<div class=\"big\">" . $da . "</div>\n";
}
else{
if($a === 1)
echo "<div>\n";
echo " <div class=\"small\">" . $da . "</div>\n";
if($a === 2)
echo "<div>\n";
}
}
I have an array of icons. Right now, we only display them in buckets of 4. So if you have 7 icons, the 4th icon on the first slide will repeat as the 8th on the second slide. That's because the 3rd index of the array is stored in that same spot. To fix this, I want to loop through the array instead of explicitly iterating icon by icon.
<?php if (!empty($icons)) { // if we have icons attributes
// NOTE: we've changed it to show as many sets as we can
// (sets of 4)
$number_of_sets = ceil(count($icons) / 4);
$k=0; // for inner iteration
for ($j=0;$j < $number_of_sets; $j++) {
$slide_total ++;
?>
<div class="cf slide icon-slide">
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon1 = $icons[$k];
$k++;
}
?>
<div class="col left">
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon1['thumb']?>" alt="<?=htmlentities($icon1['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon1['post_title']?></h4>
<p><?=$icon1['post_content']?></p>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon2 = $icons[$k];
$k++;
}
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon2['thumb']?>" alt="<?=htmlentities($icon2['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon2['post_title']?></h4>
<p><?=$icon2['post_content']?></p>
</div>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon3 = $icons[$k];
$k++;
}
?>
<div class="colR right">
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon3['thumb']?>" alt="<?=htmlentities($icon3['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon3['post_title']?></h4>
<p><?=$icon3['post_content']?></p>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon4 = $icons[$k];
$k++;
}
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon4['thumb']?>" alt="<?=htmlentities($icon4['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon4['post_title']?></h4>
<p><?=$icon4['post_content']?></p>
</div>
</div>
</div>
</div> <!-- // end icon slide -->
<?php
} // end for $j (number of sets of 4 icons
?>
My proposed solution:
<?php if (!empty($icons)) {
$num_cols = 2;
$i = 0;
$slide_items = 4;
?>
<div class="cf slide icon-slide">
<?php foreach ( $icons as $icon ) {
echo $i++%$num_cols==0 ? '</div><div class="col" style="width: 250px;">' : '';
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon['thumb']?>" alt="<?=htmlentities($icon['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon['post_title']?></h4>
<p><?=$icon['post_content']?></p>
</div>
</div>
<?php } } // end if we have icons attributes ?>
I'm having trouble figuring out how to make another slide after I hit 4 icons. Adding the following line before the end of the foreach loop hasn't worked.
echo $i++%$slide_items==0 ? '</div><div class="cf slide icon-slide">' : '';
Here's some logic for the loop:
$i = count( $icons );
if ( $i % 4 != 0 )
$i = $i + ( $i % 4 );
for( $n = 0; $n < $i; $n++ )
{
if ( $n % 4 == 0 )
{
// code to open a row here
}
// code to open a column here
// echo your icon here, use isset() or !empty().
// code to close a column here
if ( $n > 0 && $n % 3 == 0 )
{
// code to close a row here
}
}
The IFs at the top is for keeping the column number consistent. Otherwise there'll be some weirdness at the end of the loop.
Hi I have been chasing my tail for a while on this one and wondered if someone could solve my headache.
Basically I am rendering 12 items to the page. Each 3 items need to be wrapped in a row like:
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
Thanks in advance.
Hi I think some code would help:
$i=0;
foreach($posts as $p) {
$i++
}
So basically within the for each I will be outputting a row and 3 items.The results are coming from a database query. I have tried a few different approaches such as
if($i == 1) {echo "<div class='row'>";}
if ($counter % 4 == 0) {
echo "</div><div class='row'>";
}
However I keep failing, please note these are just snippets of code.
You need to use two loops:
// Outer loop for each row
for ($row = 0; $row < 4; $row++) {
echo '<row>';
// Inner loop for the items
for ($item = 0; $item < 3; $item++) {
echo '<item>';
}
echo '</row>';
}
You should have done it yourself. it needs to know very basic of loop.
try like this:
for($i=0;$i <= 3; $i++){ //outer loop for 12 times
echo "<row>"; // start row
for ($j=0;$j<3;$j++){ // inner loops for echoing 3 times
echo "<item>"; //echo item
}
echo "</row>"; // end row
}
demo : https://eval.in/107129
I have used "\n" for new line in demo. if you needed new line then you can use <br />
So I haven't programmed in a while, but i decided to tackle a small web app to get back in the game. Im having a bit of trouble though, and its kind of annoying because I know the answer is simple. So i'm making a databaseless image gallery, and i'm using Twitter Bootstrap as the front end. I want to display the images that i'm reading from a directory using the classic bootstrap row setup like this:
<div class="row">
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
</div>
The problem is that I can only put four images into a row so I cant just do something like:
<div class="row">
<?php echo"$img";?>
</div>
How can I echo a
<div class="row">
every four
<?php echo"$img";?>
I feel like a nested loop may work, but i just cant seem to get it.
Thanks.
You need a loop with an index; then you can check if the index is divisible by 4:
if ($i % 4 == 0) {
?><div class="row"></div><?php
}
Alternately, you can array_chunk your data, and run a nested loop on the results, outputting the row in the outer loop.
For each row
for($i=0; $i<$num_item; $i++) {
Start a new row before the first item and every 4th item following
if($i % 4 == 0) {
echo '<div class="row">';
}
End a row after the 4th item and every 4th item following
if($i % 4 == 3) {
echo '</div>
}
Full code:
for($i=0; $i<$num_item; $i++) {
if($i % 4 == 0) {
echo '<div class="row">';
}
// Print the item here
if($i % 4 == 3) {
echo '</div>
}
}
When dealing with a lot of html code using the (notice the colon and endif)
<?php for (index; condition; step) : ?>
<h1>HTML STUFF</h1>
<?php endif; ?>
alternative syntax is a bit cleaner than the conventional markup.
I would suggest:
<div class="row">
<?php for($i = 0; $i < $total_pics; $i++): ?>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="<?php echo $img_link; ?>">
</div>
<?php if ($i % 4 == 3 && $i < $total_pics): ?>
</div>
<div class="row">
<?php endif;
endfor; ?>
</div>
This allows the new row only to be put in place if there are more pictures to show and after the fourth one only.
This allows the html code to be indented as you want and clean the php code up a bit in the process. This also allows the initial row to be self closing if there are no pictures to show.
I have this html code:
<div class="row elem2">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="row elem4">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="row elem3">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
and I am looking for a way to implement it in my php while (wordpress).
The while is as
while ( have_posts() ) : the_post();
echo '<div class="item"></div>';
endwhile;
I've tried a lot of stuff, but none have worked. I need to divide every 2 items and put them in a wrap <div class="row elem2"> after that the next 4 items in <div class="row elem4"> and after that the next 3 items in <div class="row elem3">
I did a lot of searching, but I am not even sure what to search for.
A little crude but here's one solution
$i = 0; // Number of items made so far in the row
$mode = 0; // Current row type enumerated by $elem
$elem = array(2,4,3); // Enumeration of the desired row sizes
while ( have_posts() ) : the_post();
// Make a new row when there's no items yet
if ($i == 0) echo '<div class="row elem'. $elem[$mode] .'">';
echo '<div class="item"></div>';
$i++;
// Once the items in the current row has reached the row's maximum size
if ($i % $elem[$mode] == 0):
echo '</div>';
$i = 0; // Reset items made for the row back to 0
$mode = ($mode + 1) % 3; // Increment mode and wrap if necessary
endif;
endwhile;
if ($i > 0) echo '</div>'; // Finish the last row if it wasn't finished
This is what the modulos was built for!