Jak předávat parametry do snippetu?
- Šaman
- Člen | 2659
Navazuje na zastaralé odpovědi těchto vláken:
Předání
proměnné snippetu uvnitř bloku
Nesoulad
snippet a form maker
Ve zkratce:
Do snippetu se předávají jen globální proměnné, protože při
překreslení snippetu se neprovede okolní kód, takže ani neexistují
lokální proměnné z okolního kódu. Nejčastěji jsem to potřeboval
obejít kvůli snippetům ve formuláři. Pár typických možností:
<?php
$this->template->_form = $this['form']; // form {snippet} workaround v beforeRender metodě
?>
{form contactForm}
{snippet errors}
{var $_form = $_control['contactForm']}
<div n:if="$_form->hasErrors()">…</div>
{snippetArea contactFormArea}
{form contactForm}
{var $template->_form = $_form}
{snippet errors}
<div n:if="$_form->hasErrors()">…</div>
Aktuálně je to i s těmi hacky ale takové divné:
- Nechci přepisovat proměnnou
$form
, protože s tou pracuje i makro{form }
- Proměnná
$_form
mi háže noticku že je deprecated, i když si ji zavádím sám ručně - Zápis
$template->form
mi píše, že zápis do$template
je v šabloně deprecated - A přitom stále není možné (?) předat snippetu proměnnou, i když je to celé obalené snippetAreou.
Za ideální bych považoval řešení:
{snippet foo, form => $form}
kde snippet jasně říká jakou proměnnou vyžaduje a je na mě, abych mu ji zajistil. Nejspíš přes snippetAreu, ale možná by se ty daly parametry předávat i v
<?php
redrawControl('foo', ['param' => 10]);
?>
Jediná dvě řešení, která mi zafungovala v Nette 2.4:
První používám, přijde mi lepší. Proměnnou $form
si
vytvářím pro každý snippet, takže ji nepřepisuji globálně.
{snippetArea contactFormArea}
{form contactForm}
{snippet errors}
{var $form = $control['contactForm']}
<div n:if="$form->hasErrors()">…</div>
Druhá možnost je v předat šabloně natvrdo $form, což samozřejmě může začít haprovat ve chvíli, kdy budu mít na stránce formulářů více.
<?php
$this->template->form = $this['contactForm']; # fígl nutný k fungování závislých selectboxů
?>
Asi by se to dalo řešit unikátní proměnnou pro každý formulář, ale přijde mi to jako drbat se nohou za krkem. Rád bych to zpracoval co nejčistěji a pak si upravil renderer, abych mohl i závislé selectboxy vykreslovat rendererem, nikoliv manuálně.
P.S. Když na to teď koukám, tak v tom řešení, u kterého píšu, že ho používám, ani nepotřebuji snippetAreu. Ten hack s načtením formu z globálního seznamu komponent ji úplně obchází. Ale raději bych použil ji, než ten hack.
Editoval Šaman (5. 1. 2018 14:07)
- David Matějka
- Moderator | 6445
to navrhovane „idealni reseni“ se mi libi, sam jsem to pred nejakou dobou zvazoval, ze bych to implementoval. mozna na to nekdy kouknu :)
- Šaman
- Člen | 2659
Ono se zavedením snippetArea by se možná dalo předávat i lokální
proměnné bez nutnosti je vyjmenovávat. Je na programátorovi, aby zajistil
že budou existovat.
Ale s tím vyjmenováním parametrů by to byl takový kompromis mezi pohodlnou
implementací a bezpečným použitím. Když je musím vypsat, tak je větši
šance, že se i zamyslím, jestli je mám skutečně k dispozici. A samotný
fakt, že se snippetem zacházím podobně jako s funkcí zase pomůže
uvědomit si, že se zpracovává vytržený z kontextu.