Php foreach loop, add to different div depending on if/else - php

My current code:
<?php if($_images){?>
<?php $i=0; foreach($_images as $_image){ $i++; ?>
<?php if($i > 2) { ?>
<div class = "largePic">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
</div>
<?php } else { ?>
<div class = "smallPic">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
</div>
<?php } ?>
<?php } ?>
<?php } ?>
So this is obviously wrong since every time an image is echo'ed it's assigned to a different div (same name but different). Is it possible to assign echoes to certain div depending on the count?
For example, first two images will be assigned to the smallPic div, then the rest will be in the largePic div.

Process the images first (storing the HTML for each image in either an array or string) and then create the div elements- see example below. This will reduce the number of opening/closing tags immensely.
Also note that if the keys of the array are numeric then the following syntax can be used instead of creating an extra variable (i.e. $i) just to track the index (so as to avoid extra bookkeeping like incrementing the variable - one of the major benefits of foreach compared to a for statement).
foreach (array_expression as $key => $value)
statement 1
<?php
$largePic = '';
$smallPic = '';
if($_images){
foreach($_images as $i => $_image){
if($i > 2) {
$largePic .= '<img src="'.$this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900).'" alt="'. $this->htmlEscape($_image->getLabel()). '" title="'. $this->htmlEscape($_image->getLabel()).'" />';
} else {
$smallPic .= '<img src="'. $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675). '" alt="'. $this->htmlEscape($_image->getLabel()). '" title="'. $this->htmlEscape($_image->getLabel()). '" />';
}
}
} ?>
<div class = "largePic"><?php echo $largePic; ?></div>
<div class = "smallPic"><?php echo $smallPic; ?></div>

What you want is to first devide your array into two arrays and then foreach through both of them.
<?php
$largeImages = array();
$smallImages = array();
foreach ($_images as $k => $v) {
if ($k > 2) {
$largeImages[] = $v;
} else {
$smallImages[] = $v
}
}
?>
<div class = "largePic">
<?php foreach ($largeImages as $_image) { ?>
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
<?php } ?>
</div>
<div class = "smallPic">
<?php foreach ($smallImages as $_image) { ?>
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
<?php } ?>
</div>

I'm not in PHP but I'm quite sure for start you can loose those extensive open/close tags (<?php ?>) and replace it with only one at the start and the end. This is hardly readable.
Then, like in many server side scripts, what you need is some kind of buffer containing HTML which you will output at the end of loop. Because what you're doing now is outputting from inside the loop, this sending multiple DIVs to client.
Create largePic nad smallPic variables contianing DIVs HTML, and append HTML to it inside loop (instead outputing it to client like you do now). Then, after loop is finished, output those two variables to client.

Related

How to target the N first iterations of a while loop?

I'm displaying images on my site. The first 18 images should be written like this:
<img class="item lazy" data-src="<?php echo $path; ?>" src="<?php echo $path; ?>" />
And the rest of them (from the 19th) should be written like that:
<img class="item lazy" data-src="<?php echo $path; ?>" />
I used a while loop but it didn't work (it would show each item displayed within the loop 18 times):
while (...) { // while loop to display items from the database
$itemCount = 0;
while($itemCount <= 18) {
// show items ($itemId)
}
}
I can't think of anything... any suggestions?
<?php
$n=0;
$dir="C:/Chose a folder";
$url="http://....";
$files=scandir($dir);
foreach($files as $filenm) {
if( $n++<18 ) echo "<img class='item lazy' data-src='$url/$filenm' src='$url/$filenm' />";
else echo "<img class='item lazy' data-src='$url/$filenm/>";
}
?>
Note, the src should be the URL of the file, not the local filename

How to apply markup to every third item in WordPress?

I am using the following markup to display different image crop sizes, depending on the item number:
<?php
$images = get_field('portfolio-gallery');
$size = 'full';
if( $images ):
?>
<ul class="cf">
<?php foreach( $images as $index => $image ): ?>
<li>
<?php if ( $index == 0 ) { ?>
<img src="<?php echo $image['sizes']['gallery-1']; ?>" alt="<?php echo $image['alt']; ?>" />
<?php } elseif ( $index == 1 ) { ?>
<img src="<?php echo $image['sizes']['gallery-2']; ?>" alt="<?php echo $image['alt']; ?>" />
</li>
<?php } endforeach; ?>
</ul>
<?php endif; ?>
However I want to know if it's possible to adjust this markup so that rather than specifying each number individually, I can tell it to apply the specific markup to every third item, for example.
To specify that the markup should apply to every third item you could use something like:
<?php if ( $index % 3 == 0 ) { ?>
<img src="<?php echo $image['sizes']['gallery-1']; ?>" alt="<?php echo $image['alt']; ?>" />
This would apply the given markup to the 1st, 4th, 7th etc. image, assuming that $index starts at 0. If you wanted to apply it to the 3rd, 6th, 9th, you would use ($index - 2) % 3 == 0 instead.

Offset PHP array results

I am looking to offset a group of PHP array results to create multiple rows of data.
For example, the first row will contain the first four array results, with the second row displaying results 5-8 and the third row containing results 9-12.
Currently, I am printing out all 12 in one list, however I'd like a bit more display control (i.e. ordering the results into columns which I can style independent of each), hence why I'd like to offset the results.
My current PHP is below:
<?php
if (empty($tmdb_cast['cast'])) {
} else {?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body"><?php
foreach($tmdb_cast['cast'] as $key => $castMember){
if ($key < 12) {?>
<li class="actor_instance clearfix"><?php
if ($castMember['profile_path'] != '') {?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" /><?php
} else {?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" /><?php
}?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li><?php
}
}?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section><?php
}?>
P.S. Apologies for how I've formatted the code in the above block - I'm still not 100% sure how to make it look "nice" on StackOverflow.
Use array_chunk to break a single dimension array into a 2D array. Then you can loop through each chunk, and then each result, to get that "offset" effect between them.
$chunks = array_chunk($tmdb_cast['cast'], 4); // 4 here, is the number you want each group to have
foreach($chunks as $key => $chunk)
{
foreach($chunk as $castMember)
{
//display castMember here
}
// add code between groups of 4 cast members here
}
First: mixing php and html this way is a very bad habbit... one day you will have to maintain your code and that day you will vomit all over your desk because you mixed different languages in one file...
That being said..
and without creating a new array:
foreach($tmdb_cast['cast'] as $key => $castMember)
{
if ($key < 12)
{
// your code goes here
// if key is 3, or 7 the code below will close the listcontainer and open a new one...
if( ($key+1)%4 == 0 AND $key <11)
echo '</ul> <ul class="section_body">';
}
}
Also replace this:
if (empty($tmdb_cast['cast']))
{
}
else {
with this:
if (!empty($tmdb_cast['cast']))
{
I'm not entirely sure what you're looking for but here's how I would format your code. Alternative syntax for 'if' is a little more readable, and the use of for loops instead of a foreach will give you the control over row numbers you say you're looking for.
<?php if( ! empty($tmdb_cast['cast'])): ?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body">
<?php
for($i = 0; $i < 12; $i++):
$castMember = $tmdb_cast['cast'][$i];
?>
<li class="actor_instance clearfix">
<?php if($castMember['profile_path'] != ''): ?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" />
<?php else: ?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" />
<?php endif; ?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li>
<?php endfor; ?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section>
<?php endif; ?>

PHP + Wordpress : foreach repeat html structure after every nth

I am trying to achieve result with below structure in foreach loop where after every two images it will repeat entire structure.
I have some basic knowledge for something I can use eg. counter++; and than %2 but don't know syntax and how to use it for my code.
<?php
function dt_attached($postid=0, $size='thumbnail', $attributes='', $linksize='full', $count=-1) {
if ($postid<1) $postid = get_the_ID();
if ($images = get_children(array(
'post_parent' => $postid,
'post_type' => 'attachment',
'numberposts' => $count,
'post_mime_type' => 'image',)))
foreach($images as $image) {
$attachment=wp_get_attachment_image_src($image->ID, 'thumbnail');
$small_image = wp_get_attachment_image_src($image->ID, 'midium');
$big_image = wp_get_attachment_image_src($image->ID, 'full');
?>
<div class="mainrow">
<div class="block">
<a href='<?php echo $big_image[0]; ?>' class='cloud-zoom-gallery' title='Thumbnail 1' rel="useZoom: 'zoom1', smallImage: '<?php echo $small_image[0]; ?>' ">
<img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> />
</a>
</div>
<!--[I want to get two images in mainrow]-->
<div class="block">
<a href='<?php echo $big_image[0]; ?>' class='cloud-zoom-gallery' title='Thumbnail 1' rel="useZoom: 'zoom1', smallImage: '<?php echo $small_image[0]; ?>' ">
<img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> />
</a>
</div>
</div>
<?php //the_attachment_link($image->ID, false, true, false); ?>
<?php }
}
?>
So what I want is if there is more than two images it will repeat entire html structure. Thanks a lot for your help
What I gathered from your comments is that you want to display two images per row, and if there's one extra image, to display a placeholder next to it in the final row.
All you need is a count of how many images there are, and whether it's an even or odd number. Then once you know you're at the last image (using an incrementing counter), you add the placeholder:
What your code doesn't do is place two images in one row. For that we need to take the modulo (%) of the counter as well.
<?php
$counter = 0;
$imgCount = count($images);
foreach ($images as $image) {
$attachment = wp_get_attachment_image_src($image->ID, 'thumbnail');
$small_image = wp_get_attachment_image_src($image->ID, 'midium');
$big_image = wp_get_attachment_image_src($image->ID, 'full');
if ($counter % 2 == 0): ?>
<div class="mainrow">
<?php endif; ?>
<div class="block">
<a href='<?php echo $big_image[0]; ?>' class='cloud-zoom-gallery' title='Thumbnail 1' rel="useZoom: 'zoom1', smallImage: '<?php echo $small_image[0]; ?>' ">
<img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> />
</a>
</div>
<?php if ($counter++ % 2 == 1): ?>
</div>
<?php endif; ?>
<?php //the_attachment_link($image->ID, false, true, false); ?>
<?php
}
// Since (if there are an odd number of images) the loop may not close the <div>,
// we have to make sure it does.
if ($counter % 2 == 0) {
?>
<!-- placeholder goes here -->
</div>
<?php
}

breaking output of php array into chunks

I have an array containing information about some images, which I am using to print a number of img html tags by a foreach loop as follows:
<?php foreach ( $images as $image ) : ?>
<img alt="<?php echo $image->alttext ?>" src="<?php echo $image->thumbnailURL ?>" />
<?php endforeach; ?>
I would like to wrap a div around every 10 images. The remainder should get a div as well.
I am thinking I need to use array_chunkon $images and wrap the above in another loop for each chunk. The little bit of math I did to start is as follows:
$pics_per_page = 10;
$imgcount = count($images);
$num_pages = ceil($imgcount/$pics_per_page);
$pages = array_chunk($images, $num_pages);
How do I proceed from here? How do I use the $images array correctly, if at all, in outputting my HTML?
Forgetting about the array_chunk method, I have the following way, but the array_chunk method seems cleaner.
for i from 1 to num_pages:
echo "<div>"
j = (i-1) * pics_per_page;
while j <= i * pics_per_page
echo "<img src = "$images[j]->thumbnailURL />";
endwhile;
echo "</div>"
Thanks for your help in advance,
Sepehr
You are using array_chunk [docs] wrongly. You just have to specify the size of each chunk:
$chunks = array_chunk($images, 10);
Then you need a nested for (foreach) loop:
<?php foreach($chunks as $chunk): ?>
<div class="someClass">
<?php foreach($chunk as $image): ?>
<img alt="<?php echo $image->alttext ?>" src="<?php echo $image->thumbnailURL ?>" />
<?php endforeach; ?>
</div>
<?php endforeach; ?>
You could use it without array_chunk too.
<?php
$imgTot = count($images);
echo '<div>';
for($i=0; $i<$imgTot; $i++)
{
if ($i % 10 == 0) {
echo '<div>';
}
echo '<img alt="'.$image->alttext.'" src="'.$image->thumbnailURL.'" />';
if ($i % 10 == 9) {
echo '</div>';
}
}
echo '</div>';
?>
See the working example here: http://codepad.org/FkdTEH91

Categories