I have modified the tpl used for the grid view to show 3 columns of content, my only issue that the code below creates unneeded divs for the view. I have a maximum of 9 items that should be output in 3 rows, 3 per column. What's the best way to modify the code below? to prevent the extra divs from being output.
<?php foreach ($rows as $row_number => $columns): ?>
<div>
<?php foreach ($columns as $column_number => $item): ?>
<?php print $item; ?>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
I would drop that notation of foreach syntax (but I think that's pretty personal :-) )
You could use the modulo to check if you just had 3 columns (if I understood your question).
<?php
// I´m assuming that $column_number is a zero based index
// if thats not the case you should add a counter to keep track of column numbers or if it is in sequence but isn't zero based you could easily update the calculates based in your starting index
foreach ($rows as $row_number => $columns) {
foreach ($columns as $column_number => $item) {
if ($column_number == 0 || $column_number%3 == 0) {
print '<div>';
}
print $item;
if ($column_number == 2 || $column_number%3 == 2) {
print '</div>';
}
}
// prevent open div tags
$total_columns = count($columns);
if ($total_columns > 0 && ($total_columns < 3 || $total_columns%3 != 0)) {
print('<div>');
}
}
I've also dropped all those opening and closing tags of php for readability.
Related
I have a database with "7" user account objects.
I have called the objects using any of the loop functions.
foreach (objects as object) {
echo '<div class="col-4>"'.object->property.'"</div>';
}
I want to add rows for each 3 columns as they are being displayed.
The above code would result in all my objects/colums/divs being nested in one row.
I want a way in which I can have the loop adding a row for every 3 columns.
Count the objects as you go. If $x divided by 3 has no remainder, close and open the next div:
$x = 0;
foreach ($objects as $object){
$x ++;
echo '<div class="col-4">"'.$object->property.'"</div>';
echo ($x % 3 == 0) ? '</div><div class="row">' : '';
}
I have a list of 6 products that i want to split in 2 lists of 3 products next to each other. The list are made within a foreach loop, the first list stops after the count == 2, so 3 items wil be displayed. The second list should start with the fourth item. How can i achieve this?
This is wat makes the first list of 3 items:
<?php
$_categoryId = explode(' ', $category['id']);
$count = 0;
$_productCollection = Mage::getModel('catalog/category')->load($_categoryId)
->getProductCollection()
->addAttributeToSelect('*')
->setOrder('date_added', 'DESC');
?>
<?php foreach ($_productCollection as $_product): ?>
<li class="category-row-list-item">
<a class="product-name" href="<?php echo $_product->getProductUrl() ?>">
<?php echo $this->htmlEscape($_product->getName()) ?>
</a>
</li>
<?php
if($count == 2) break; // Stop after 3 items
$count++;
?>
<?php endforeach ?>
Best regards,
Robert
For simplicity you could repeat the foreach statement but doing the opposite and continue on the first three items.
<?php foreach ($_productCollection as $_product): ?>
<?php
$count++; // Note that first iteration is $count = 1 not 0 here.
if($count <= 3) continue; // Skip the iteration unless 4th or above.
?>
<li class="category-row-list-item">
<a class="product-name" href="<?php echo $_product->getProductUrl() ?>">
<?php echo $this->htmlEscape($_product->getName()) ?>
</a>
</li>
<?php endforeach ?>
The keyword continue is used in loops to skip the current iteration without exiting the loop, in this case it makes PHP go directly back to the first line of the foreach-statement, thus increasing counter to 4 (since 4th, 5th and 6th is what we're after) before passing the if statement.
Commentary on the approach
I kept it coherent with your existing solution but a more clean way in this case would probably be to use the built in Collection Pagination.
If you use ->setPageSize(3) you can simply iterate the collection to get the first three products and then use ->setCurPage(2) to get the second page of three items.
I'm linking this blog post on the topic here just to give you an example of how it's used but since I don't know your comfort level in working with collections I retain my first answer based on your existing code.
Something like that with modulo function for have new array each 3 items :
$count = 1;
$count_change = 1;
$key = 0;
$yourList = array(
"1",
"2",
"3",
"4",
"5",
"6",
);
foreach ($yourList as $item) {
if (!isset($$new_list)) {
$new_list = "list" . $count_change . "";
$$new_list = array();
}
if ($count % 3 == 0) {
$key = 0;
$count_change++;
$new_list = "list" . $count_change . "";
$$new_list = array();
}
$$new_list[$key] = $item;
$count++;
$key++;
}
Hope this helps.
I was wondering if anyone could give me a hand with this...
Basically I am trying to modernize the news system of my site but I can't seem to limit the amount of posts showing in the foreach loop that is on my blog part of the site. I need to skip the first instance as it is already promoted at the top of the page. I've tried various google searches but im getting results for C++ Perl and python, what is really irritating. I just need a simple PHP solution. I'll pop my code below and see if anyone can help. Thanks for any help in-advance. And please remember to leave your responses as an answer so I can mark them up if they helped ;)
<div class="view22 full" style="margin-top:0;">
<h3>Recent News and Announcements</h3>
<?php foreach ($articles as $article) {
?>
<div class="ah7_ clearfix">
<p class="date"><?php echo date('F j', $article['article_timestamp']); ?>, <?php echo date('Y', $article['article_timestamp']); ?></p>
<h3><?php echo $article['article_title']; ?></h3>
</div>
<?php
}
?>
</div>
I assume that the $articles array has keys starting with 0. How about modifying the loop like this:
foreach ($articles as $key => $article)
and checking if $key is 0 at the beginning?
if($key == 0)
continue;
If the array keys are different: Create a new variable $i, set it to 0 and increase the value by 1 in every foreach loop iteration.
$i = 0;
foreach ($articles as $article) {
$i++;
if($i == 1)
continue;
elseif($i > 8)
break;
//the other code goes here
}
In case it is based on a SQL query, using "limit" might help to reduce load!
There are a few things you can do:
If you $articles is an array of array, having continous indexes, use a for loop instead of foreach and do something like
for ($i = 1; $i < 8 : $i++ ) {
// and access it like
$articles[$i]['some_index'] ...
}
If it is not then you can use an external counter
Say
$counter = -1;
foreach ( $articles as $article) {
$counter++;
if (!$counter) continue;
if ($counter > 7 ) break;
...// your code //
}
You can change your Mysql query to give you only the desired data, using LIMIT and OFFSET
To remove the first instance you can manually unset the item ($articles[0]) after making a copy of it or printing it as a featured news.
To limit the number of post you can use the mysql LIMIT Clause;
Or you can do something like this
foreach($articles as $key => $article){
if($key===0)
continue;
if($key===8)
break;
echo $article;// or_do_whatever_youwant_with($article);
}
I have a foreach loop in php.
When the loop is greater than 2 items I would like to display some text instead of the loop. Is this possible?
For example: A loop of 2 or less items shows= item 1, item2
The loop of more items shows the text = Mulitple items.
The example code for indication:
$count++;
foreach($attValConfig as $attValConfigSingle) {
if ($attValConfigSingle["frontend_label"] == "LABELTEXT") {
echo ('<div class="attributes_row">Text</div>');
foreach($attValConfigSingle['values'] as $attValConfigSingleVal) {
if ($count++ > 2) { echo 'SomeNewText'; }
else echo "<option>"list of items"</option>";
I think you want to break in your if statement:
if ($count++ > 2) {
echo 'SomeNewText';
break;
}
You can count the array before looping:
if(count($attValConfigSingle['values']) > 2) {
// More than 2 items
echo "Lots of things";
} else {
// 2 items or less
foreach($attValConfigSingle['values'] as $value) {
// ...
}
}
Edit:
Maybe I didn't understand you correctly. If you want the text:
item 1, item 2, other items...
Then you need to use break to break out of your loop:
foreach($attValConfigSingle['values'] as $attValConfigSingleVal) {
if ($count++ > 2) {
echo 'SomeNewText';
break;
} else {
echo "<option>"list of items"</option>";
}
}
Just declare a variable in which you store your text built during the foreach loops. When you're out of it, print this string if count is less than 3, your other text otherwise.
I'm trying, but I'm stucked with the logic... so, I have this:
$max_items=10;
echo '<table>';
echo '<tr>';
foreach ($feed->get_items(0, $max_items) as $item):
echo '<td>';
echo $some_value;
echo '</td>';
endforeach;
echo '</tr>';
echo '</table>';
I want to show the results like this:
[1][2]
[3][4]
[5][6]
[7][8]
[9][10]
I have to use a while statement? A for loop? Inside or outside the foreach code?
I really don't get it...
Thanks for any kind of help
Here's a very simple example of how to do this sort of HTML building.
<?php
$data = range( 'a', 'z' );
$numCols = 2;
echo "<table>\n";
echo "\t<tr>\n";
foreach( $data as $i => $item )
{
if ( $i != 0 && $i++ % $numCols == 0 )
{
echo "\t</tr>\n\t<tr>\n";
}
echo "\t\t<td>$item</td>\n";
}
echo "\t</tr>\n";
echo '</table>';
This way, you can change $numCols to be 3 or 4 (or any number) and always see that number of columns in the output, and it does so without using an nested loop.
Take a look at this link to Displaying Recent Posts On a Non-WordPress Page. I think what you may be looking for is a way to loop over the objects get methods. For that you will need a nested loop and some sort of reflection.
I was just recently working with SimplePie on the February release of Cogenuity so this is still fresh in my mind.
Your $some_value variable never gets initialized.
The $item object will have such methods as get_permalink(), get_title(), get_description(), and get_date()