Latte – výpis dat po sloupcích

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Elijen
Člen | 171
+
0
-

Potřeboval bych vypsat pole hodnot do N sloupců, ale nikoli po řádcích nýbrž po sloupcích. Mám-li například pole:

$pole = array('Adéla', 'Andrea', 'Bára', 'Klára', 'Petra', 'Míša', 'Zuzka');

Jednoduše ho vypíši do dvou sloupců pomocí makra foreach do podoby:

₊-------+--------+
| Adéla | Andrea |
| Bára  | Klára  |
| Petra | Míša   |
| Zuzka |        |
+-------+--------+

Já bych ale potřeboval vypsat položky takto:

₊--------+-------+
| Adéla  | Petra |
| Andrea | Míša  |
| Bára   | Zuzka |
| Klára  |       |
+--------+-------+

Dal bych ruku do ohně za to, že jsem na to již viděl komponentu nebo latte makro, ale za boha to nemohu vygooglit. Samozřejmě se to dá udělat ošklivě pomocí x podmínek v šabloně, ale to mi nepřijde příliš elegantní. Jak byste to řešili vy?

Filip Procházka
Moderator | 4668
+
0
-

Já bych to řešil vhodným naformátováním struktury v render metodě presenteru

$pole = array('Adéla', 'Andrea', 'Bára', 'Klára', 'Petra', 'Míša', 'Zuzka');
$this->template->columns = array_partition($pole, 2);

pomocí nějaké šikovné funkce

function array_partition($array, $columns = 2)
{
	$result = array();
	array_walk(array_values($array), function ($item, $key) use (&$result, $columns)) {
		$result[$key%$columns][] = $item;
	};
	return $result
}

abych si to mohl pěkně vykreslit

<tr n:foreach="$rows as $row">
	<td n:foreach="$row as $item">{$item}</td>
</tr>

Editoval HosipLan (22. 1. 2012 21:26)

redhead
Člen | 1313
+
0
-

Neslouží k tomu makra first a last?

<table n:inner-foreach="$pole as $item">
        {first 2}<tr>{/first}
        <td>{$item}</td>
        {last 2}</tr>{/last}
</table>

EDIT: toto ovšem vypíše tabulku 1. způsobem, pardon.

Editoval redhead (22. 1. 2012 22:49)

Aurielle
Člen | 1281
+
0
-

Resp. grid rendering :)
(sám jsem ho zatím nepoužil, ale to co píše @redhead tak vypadá)

Filip Procházka
Moderator | 4668
+
0
-

Makra first a last ti buďto pro prvni, poslední nebo pro n-tou iteraci „vykreslí“ obsah.

Co píše @**redhead** dělá právě přesně tu první tabulku. @**Elijen** ale chce vykreslovat „po sloupcích“, což takto neuděláš, musíš si na to to pole upravit, nebo podmínkovat jako o závod.

redhead
Člen | 1313
+
0
-

Ahá, špatně jsem pochopil dotaz. Máš pravdu.

Elijen
Člen | 171
+
0
-

Díky za reakce,

@HosipLan Tvá funkce nefunguje jak by měla. Vypisuje první variantu, jen jaksi transformovaně (do dvou řádků). Asi by bylo výhodnější použít array_chunk na rozdělení po sloupcích a položky v šabloně vypsat pomocí {while} či {for}.

Zatím jsem to vyřešil pomocí seznamu <ul> pro každý sloupec a CSS atributu float:

render:

$columnCount = 2;
$items = array('Adéla', 'Andrea', 'Bára', 'Klára', 'Petra', 'Míša', 'Zuzka');
$this->template->items = $items;
$this->template->columnSize = ceil(count($items) / $columnCount);

latte:

{foreach $items as $item}
   {first $columnSize}<ul>{/first}
      <li>{$item}</li>
   {last $columnSize}</ul>{/last}
{/foreach}

Tento problém ale řeším poměrně často a někdy by mohlo být nutné použít tabulku místo seznamu (i když sémanticky se jedná vlastně o seznam).

Editoval Elijen (23. 1. 2012 14:32)

llook
Člen | 407
+
0
-

Můžeš použít cyklus for, ale moc elegantní to nebude:

{var $values = array_values($pole)}
{var $halfIndex = ceil(count($values) / 2)}
{for $i = 0, $j = $halfIndex; $i < $halfIndex; $i++, $j++}
    {$values[$i]} | {ifset $values[$j]}{$values[$j]}{/ifset} <br/>
{/for}