4 columns in smarty - php

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>

Related

Smarty foreach not looping through objects in array

I have an array with multiple objects in it that I'm trying to loop through, but the foreach only loops once, like it's only finding the array, but not the objects within.
myArray = [
{ name: 1},
{ name: 2},
{ name: 3}
];
{foreach from=myArray item=item key=key}
console.log("{$key}"); -> prints 0
{/foreach}
After it prints 0, it stops running then it should also print 1 and 2 for the indexes.
I've tried nesting foreachs, but when I try that, it errors out. Something like this
{foreach from=myArray item=item key=key}
{foreach from=item item=value key=i}
console.log("{$i}"); -> error
{/foreach}
{/foreach}
Also, when I console.log myArray[0], it prints {name: 1} as it should, but the foreach isn't behaving the same way.

Smarty concat/foreach assignment

I have a main array:
$occupations = ['hs','uni','parent'];
and other multiple array of type
$columns_hs;$columns_uni;
etc.
I want to foreach through the "$occupations" array and then foreach through the other arrays but cant seem to get the right syntax.
Here is my code:
{foreach from=$occupations item=ov key=ok}
{foreach from=$columns_`$ov`}
do something
{/foreach}
{/foreach}
I am using smarty 2.
You can try to create your own varible with assign
Declare one array colums
$colums = array(
'hs' => [1,2,3,4],
'uni' => [5,6,7,8]
);
and your code in foreach is
{foreach from=$occupations item=ov key=ok}
{foreach from=$columns[$ov]}
do something
{/foreach}
{/foreach}

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: check if variable is in array

I'm using php with smarty. In php I have two arrays:
$code = Array
(
[n_id] => 1
[t_code] => ABC123
[t_description] => Test code
[b_enabled] => Yes
[n_type] => 3
[dt_start] =>
[dt_end] =>
[n_min_req_gbp] => 0
[n_min_req_usd] => 0
[n_amount_gbp] =>
[n_amount_usd] =>
[n_max_overall_gbp] =>
[n_max_overall_usd] =>
[n_extra] => 6
[b_reuse] => No
[n_applications] => Array
(
[0] => 2
)
)
and
$all_application = Array
(
[1] => New registration
[2] => Mid-subscription upgrade
[3] => Subscription renewal
[4] => Additional purchase
)
Note that the second array may - and will - grow, this is the reference data, from which n_applications array field in the first array is built. That is, the array in n_applications will contain a subset of keys from the $all_applications arrays.
Now, I'm assigning these two arrays into the template:
$template->assign('code', $code);
$template->assign('apps', $all_applications);
And in the template, I'm creating a form for editing the fields in the $code array. Everything is working fine except the 'applications' selection. I want to pre-select those apps that are already in the n_applications field. So, in my template I have this:
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
{assign var=v value=$k|#array_search:$code['n_applications']}
<option value="{$k}"{if $v!==FALSE} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
However this doesn't work as expected - and ALL options end up being selected. I tried using in_array function - but with the same result. What's the best way to achieve what I'm after?
After a bit of struggling in all possible directions, I finally managed to pull it off like this (smarty code only)
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
{if #in_array($k, $code.n_applications)}
{assign var=v value=true}
{else}
{assign var=v value=false}
{/if}
<option value="{$k}"{if $v} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
And this did the trick.
You can do it like this:
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
<option value="{$k}"{if in_array($k, $code.n_applications)} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
I've done something similar a few years back, and stumbled over the same logical challenge.
My solution was to modify the base array (in your case, $all_applications) while adding another key there (maybe ['opt_selected']). I left the default value empty, and for the data I wanted to have selected, I've changed the value to, guess what, ... selected="selected".
This makes it rather easy for your Smarty template:
<option value="{$k}" {$a.opt_selected|default:''}>{$a|escape}</option>
It might not be the best solution, but it helps leaving alot of code out of the template where I usually don't want too much program logic.
Update
To counter having the HTML part in your php code, you might as well just flag the array:
$all_applications['opt_selected'] = 1
...and then arrange Smarty like this:
<option value="{$k}" {if $a.opt_selected eq '1'}selected="selected"{/if}>
{$a|escape}
</option>

Smarty: Outputting Rows Based on # of Items in Array

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>

Categories