Smarty: Outputting Rows Based on # of Items in Array - php

I am using Smarty to output an array to an HTML table. I want each row of the table to have no more than 8 items in it. If the array has more than 8 items then the code would make a new row for the overflowing items.
How can I do this? Is this clear?

It's been a long time since I've used Smarty, but you should be able to do this like this:
<tr>
{foreach from=$items key=myId item=i name=foo}
{if $smarty.foreach.foo.index % 8 == 0 && $smarty.foreach.foo.index > 0 }
</tr><tr>
{/if}
<td>{$i.label}</td>
{/foreach}
</tr>
The modulus operator only returns 0 if the index is dividable by 8, So before every 9th item it adds a new row. We don't want this for the first item to happend so let's check that as well.

Here's how I did it in the past:
<table>
{foreach from=$array item='array_item' name='array_items'}
{if $smarty.foreach.array_items.first}
{* first item - start of all the rows *}
<tr><td>{$array_item}</td>
{elseif $smarty.foreach.array_items.index % 8 == 0}
{* 8 items added to row - start new row *}
</tr><tr><td>{$array_item}</td>
{elseif $smarty.foreach.array_items.last}
{* last item - end the row (or add logic to fill out row with empty cells if needed) *}
<td>{$array_item}</td></tr>
{else}
{* normal item - add cell *}
<td>{$array_item}</td>
{/if}
{/foreach}
</table>

Related

How to loop over an array in Smarty/Prestashop?

I use this code in Prestashop
{if (strpos($product.name, 'TVNUMBER1') !== false)}
THIS PRODUCT IS IN SALE
{/if}
So whenever I want to display that certain products are in sale, I have to go line by line, specifying the same product i.e."TVNUMBER1". I want to be able to write an array detailing all the products I have in sale "TV1, TV2, TV3", and get a code like this:
{if (strpos($product.name, '$array') !== false)}
THIS PRODUCT IS IN SALE
{/if}
I've tried similar examples found here, but I can't get them to work, either in Prestashop or in PHP testers online. It looks super simple, but I can't get around it.
I think what you want is the in_array php function, that check if a given $needle is or not in an array.
So what you should do is :
{if (in_array($product.name, '$array') !== false)}
THIS PRODUCT IS IN SALE
{/if}
Then in your controller you can assign the array to smarty :
$arr = array('TVNUMBER1', 'TVNUMBER2', 'TVNUMBER3');
$smarty->assign('myArray', $arr);
It seems you are using Smarty as template engine. So you could do something like this (from the doc).
In the controller
//Give it to the view
$arr = array('TVNUMBER1', 'TVNUMBER2');
$smarty->assign('myArray', $arr);
And in the view
//In the view, loop over the array
{foreach from=$myArray item=productName}
//If your product is among the in-sale ones, show the message
{if (strpos($product.name, productName) !== false)}
THIS PRODUCT IS IN SALE
{/if}
{/foreach}

Print tracking number on prestashop invoice

how can I add/print tracking number on invoice?..
I used the code below
{l s='Tracking Number:' pdf='true'}
{$order->shipping_number}
returns blank, but on view order it has a tracking number. (image below)
orders->shipping_number field is blank.
Thanks.
adding on invoice.tpl
{foreach from=$order->getShipping() item=line}
{if $line.url != '' || $line.tracking_number != ''}
{'Tracking Number : '}
{$line.tracking_number}
{/if}
{/foreach}
solves the issue.

4 columns in smarty

Is this even on the same planet as the correct code format in smarty.
{foreach from=$watchvendor item=item}
<td>{$item.id} - {$item.nick}</td>
{math equation= 'x/y' x=$item y='4' assign='howmany'}
{if $howmany eq 0}
</tr>
<tr>
{/if}
{/foreach}
i assume that $item is the element identity in the array ie.. 0 1 2 3 4 5 so when that did not work i tried this as well
{math equation=" 'x/y' x=count($watchvendor) y='4' assign='howmany'}
so basically if the loop divided by 4 = 0 its time for a new row.
The basic code without the extra math works fine i just want it spread out on the page.
ok i used
{$item|#debug_print_var}
and got this
Array (2)
id => 8
nick => "bbuddy" Array (2)
id => 7
nick => "span" Array (2)
id => 6
nick => "LJ" Array (2)
id => 5
nick => "JD" Array (2)
id => 4
nick => "Jsmith159"
sure is a strange looking array, first time i have ever seen a smarty array - no element id's
This seems to work...
<table class="ow_table_1 ow_form ow_automargin">
<tr>
{assign var=cnt value=0}
{foreach from=$watchvendor item=item}
{assign var=cnt value=$cnt+1}
<td>{$item.id} - {$item.nick}</td>
{if $cnt eq 4}
</tr>
<tr>
{assign var=cnt value=0}
{/if}
{/foreach}
</tr>
</table>

Smarty assign and display two dimensional array

I want to get a two dimensional array's data and display it in a html file using smarty:
The idea is as following: my array contains several arrays everyone contains the category name in the first offset and the attached links to this category
1-file php
$categories_links = array();//array that contains some catgories name with the attached links
//some dummy data
$categorie1="Horror movies";
$link11="http://www.movie11.com";
$link12="http://www.movie12.com";
$link13="http://www.movie13.com";
$categories_links[] = array($categorie1, $link11, $link12,$link13);
$categorie2="Action movies";
$link21="http://www.movie21.com";
$link22="http://www.movie22.com";
$categories_links[] = array($categorie2, $link21, $link22);
$smarty->assign('categories_links' , $categories_links );
$smarty->display('file.html');
2-file html
{foreach key=categorie item=categorie from=$categories_links}
foreach key=categorie item=categorie from=categorie}
<!--
1.display only the first item in every array as the category name
2.display the rest as the links attached to the above category
//-->
{/foreach}
{/foreach}
Assuming you use Smarty 3 (you haven't mentioned anything about Smarty 2) you can use the following code:
{foreach $categories_links as $categorie}
<p>
{foreach $categorie as $item}
{if $item#first}
<strong>Category name: {$item}</strong><br />
{else}
{$item}
{/if}
{/foreach}
</p>
{/foreach}
Output for this will be:
Category name: Horror movies
http://www.movie11.com http://www.movie12.com http://www.movie13.com
Category name: Action movies
http://www.movie21.com http://www.movie22.com
EDIT
As you mentioned in comment you want solution for Smarty 2 you need to use in you Smarty template file:
{foreach key=id item=categorie from=$categories_links}
<p>
{foreach item=item from=$categorie name=list}
{if $smarty.foreach.list.first}
<strong>Category name: {$item}</strong><br />
{else}
{$item}
{/if}
{/foreach}
</p>
{/foreach}
This will give you output:
Category name: Horror movies
http://www.movie11.com http://www.movie12.com http://www.movie13.com
Category name: Action movies
http://www.movie21.com http://www.movie22.com
(exactly the same as the one in Smarty 3)
I'd refactor the data array to use the category name as a key.
$categories = array(
'Horror movies' => array(
'link1',
'link2',
/...
),
'Action movies' => array(
'link1',
'link2',
/...
),
);
$smarty->assign("categories", $categories);
Then you can use it easily in Smarty
{foreach from=$categories key=category item=links}
Category: {$category}
{foreach from=$links item=link}
{$link}
{/foreach}
{/foreach}
It is much easier to use that way.

smarty template variable not clear

I am trying to understand developing web apps with PHP and smarty this is the book
there is a file departments_list.tpl
{* departments_list.tpl *}
{load_presentation_object filename="departments_list" assign="obj"}
{* Start departments list *}
<div class="box">
<p class="box-title">Choose a Department</p>
<ul>
{* Loop through the list of departments *}
{section name=i loop=$obj->mDepartments}
{assign var=selected value=""}
{* Verify if the department is selected to decide what CSS style to use *}
{if ($obj->mSelectedDepartment == $obj->mDepartments[i].department_id)}
{assign var=selected value="class=\"selected\""}
{/if}
<li>
{* Generate a link for a new department in the list *}
<a {$selected} href="{$obj->mDepartments[i].link_to_department}">
{$obj->mDepartments[i].name}
</a>
</li>
{/section}
</ul>
</div>
{* End departments list *}
I do not understand in above file one line which is
{section name=i loop=$obj->mDepartments}
how does name=i works I what is i initialized to and how can a loop start from i,
secondly above file is using a file function.load_presentation_object.php
<?php
// Plug-in functions inside plug-in files must be named: smarty_type_name
function smarty_function_load_presentation_object($params, $smarty)
{
require_once PRESENTATION_DIR . $params['filename'] . '.php';
$className = str_replace(' ', '',ucfirst(str_replace('_', ' ',$params['filename'])));
// Create presentation object
$obj = new $className();
if (method_exists($obj, 'init'))
{
$obj->init();
}
// Assign template variable
$smarty->assign($params['assign'], $obj);
}
?>
in above file a parameter $params has been used in last line
$smarty->assign($params['assign'], $obj);
as far as I can understand from file departments_list.tpl passes on parameter to function.load_presentation_object.php
as
{load_presentation_object filename="departments_list" assign="obj"}
so when following is called
function smarty_function_load_presentation_object($params, $smarty)
$params=depratments_list and $smarty=obj
so how does
$smarty->assign($params['assign'], $obj);
work what is $params['assign'] in above?
{load_presentation_object filename="departments_list" assign="obj"}
translated to php will be:
smarty_function_load_presentation_object(
array(
'filename' => 'departments_list',
'assign' => 'obj'
),
$smarty
);
Every parameters specified in smarty template are passed as associative array in first argument. Second is always current smarty object.
As for
{section name=i loop=$obj->mDepartments}
it is simple for loop:
for ($i=0; $i < count($obj->mDepartments); $i++) {
$current = $obj->mDepartments[$i];
}

Categories