I have a multidimensional array and would like to generate a definition list grouped by name and values concatenated comma separated.
Through the smarty foreach loop, I manage to generate a definition list but was unable to group by the name nor concatenate the respective values.
The array looks like this:
Array (
[0] => Array (
[name] => Fabric
[value] => Silk
)
[1] => Array (
[name] => Paper
[value] => A4
)
[2] => Array (
[name] => Paper
[value] => A5
)
)
The smarty foreach loop:
<dl>
{foreach from=$products item=feature}
<dt>{$feature.name}</dt>
<dd>{$feature.value}</dd>
{/foreach}
</dl>
So far I just managed to get a definition list like this:
<dl>
<dt>Fabric</dt>
<dd>Silk</dd>
<dt>Paper</dt>
<dd>A4</dd>
<dt>Paper</dt>
<dd>A5</dd>
</dl>
This is how I need to get it:
<dl>
<dt>Fabric</dt>
<dd>Silk</dd>
<dt>Paper</dt>
<dd>A4, A5</dd>
</dl>
Any help would be greatly appreciated.
I forgot to mention that I can't change the array. I have to solve this in the .tpl file.
CodePudding user response:
To do it at the template level you can create an array using the following syntax to group the products by name:
{foreach from=$products item=feature}
{$grouped[$feature.name][] = $feature.value}
{/foreach}
Then in your foreach add a reference to the key which is the product name and implode the values:
<dl>
{foreach from=$grouped key=$key item=features}
<dt>{$key}</dt>
<dd>{", "|implode:$features}</dd>
{/foreach}
</dl>
CodePudding user response:
// Setup:
$products =
[
['name' => 'Fabric', 'value' => 'Silk'],
['name' => 'Paper', 'value' => 'A4'],
['name' => 'Paper', 'value' => 'A5'],
];
First lets group your products by name with function:
function groupByKeys($array)
{
$result = [];
foreach($array as $key => $value) {
if(!array_key_exists($value['name'], $result)) {
$result[$value['name']] = [];
}
$result[$value['name']][] = $value['value'];
}
return $result;
}
$groupedproducts = groupByKeys($products);
Then just show them in template, values comma separated:
<dl>
{foreach from=$groupedproducts key=k item=v}
<dt>{$k}</dt>
<dd>{', '|implode:$v}</dd>
{/foreach}
</dl>