Pokud používáte SMARTY šablony, možná jste již narazili na problém s vypsáním pole, které nemá přesně daný počet úrovní. Typický příklad je třeba menu, kdy každý odkaz může obsahovat sub položky.
První krok většinou obnáší naplnění pole z databáze. Tímto tématem se článek nezabývá, různé přístupy k uložení struktur v databázi lze nalézt například v článku na Intervalu.
Předpokládejme tedy, že pole již máte naplněné v proměnné, tu jste předali šabloně a nyní byste rádi pole nějak strukturovaně vypsali.
Pole může mít takovouto podobu:
Array (
[0] => Array (
[nazev] => SEO
[url] => seo
)
[1] => Array (
[nazev] => Šablony
[url] => sablony
[active] => 1
[submenu] => Array (
[0] => Array (
[nazev] => Smarty
[url] => sablony-smarty
[active] => 1
)
[1] => Array (
[nazev] => Flexy
[url] => sablony-flexy
)
)
)
[2] => Array (
[nazev] => PHP
[url] => php
)
)
V příkladu jsou naznačeny 2 úrovně zanoření, obecně jich může být libovolný počet. Pro práci s polem tak nebude stačit jednoduchý cyklus, který je vestavěn ve Smarty (foreach a section), je třeba použít rekurzivní funkci.
Tvorba vlastních funkcí a pluginů pro Smarty se může zdát na první pohled složitá, ve skutečnosti je ale velmi jednoduchá. Celkem obsáhlý úvod do této problematiky lze nalézt například zde. V adresáři smarty se nachází složka plugins, kde jsou umístěné již hotové funkce pro Smarty. Vlasní rozšíření můžete přidat sem, doporučuji ale vytvořit si pro ně samostatnou složku, lépe si o nich následně udržíte přehled. O tomto adresáři je následně nutné Smarty informovat:$smarty->plugins_dir = array('smarty/plugins',
'smarty/plugins_user');
V poli je nutné uvést i cestu k původním pluginům, které by jinak nebyly dostupné.
Tím je veškerá konfigurace hotová, nyní již můžeme vytvořit samotnou funkci. Ta musí být umístěna v samostatném souboru, který má název ve tvaru function.nazevfunkce.php. Soubor pojmenujeme například function.vypismenu.php a umístíme ho do složky smarty/plugins_user. Obsah souboru bude tvořit klasická PHP funkce. Její jméno se také musí držet konvencí - smarty_function_nazevfunkce. V našem případě tak bude název smarty_function_vypismenu.
Každá takováto funkce očekává 2 vstupy - pole proměnných a objekt Smarty. O nic se však nemusíme starat, stačí se soustředit na proměnné, jak uvidíme v příkladu:
function smarty_function_vypismenu($params, &$smarty) {
$menu = $params["menu"];
echo "<ul>";
foreach ( $menu as $klic=>$polozka) {
if ($polozka['active']) $active = ' class="active"';
else $active = false;
echo "<li><a href=\"/$polozka[odkaz]\"$active>$polozka[nadpis]</a>";
if ($polozka['submenu']) {
$parametry = array ( "menu" => $polozka['submenu'] );
smarty_function_vypismenu($parametry, $smarty);
}
echo "</li>";
}
echo "</ul>";
}
Pro názornost jsem kód více rozepsal, dal by se napsat úsporněji. Jak jsem již zmínil, proměnná $params obsahuje pole (i v případě předání jediného parametru), proto si z něj menu vytáhneme. Další kód je myslím jasný, v cyklu projdeme menu a vypíšeme ho v seznamu.
Jediné zajímavé místo je, když položka obsahuje sub menu. V tom případě se vytvoří pole z odpovídající položky a opět se zavolá funkce smarty_function_vypismenu pro její výpis.
Nyní již máme funkci hotovou a můžeme ji v šaloně použít. Zápis je jednoduchý:{vypismenu menu=$menu}
Uvedený plugin se dá snadno modifikovat pro jakékoli použití, v němž je třeba vypsat pole. Tento postup může mít také jednu nevýhodu - Pokud se Smarty pracuje kodér, nemusí mu být zápis složitějších konstrukcí v PHP srozumitelný. Na druhou stranu je v některých případech nutné šáhnout k vytvoření vlastních pluginů - speciálně u složitějších výpisů v podstatě není jiná cesta.
26.08.08 - Programování - 6980x -
Karma: 18.

Stačilo by mít všechny prvky menu ve dvou rozměrech s určením jejich rodiče a hloubky zanoření. Ne takhle přes pole [submenu]. Pak to jde jednoduše bez funkce. Někdy je lepší dostat do šablony data v lepším formátu, než trápit Smarty.
Odpověď na pix — #1 Ano, stejného cíle lze dosáhnout různými cestami. Práce s takovýmto typem pole přímo ve Smarty se někdy může hodit a funkci lze jednoduše upravit, nemusí pouze vypisovat menu.