Jak předávat parametry do snippetu?

Šaman
Člen | 2635
+
0
-

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
+
+2
-

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 | 2635
+
0
-

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.