Čarodějnická supertovárnička nejen na formuláře

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

Kdy jindy zveřejnit řešení s větším než malým množstvím magie, než dnes, nejmagičtější večer v roce.. :)

Tak tu je: https://github.com/…SuperFactory


Motivace:

  • některé komponenty se opakují ve více presenterech, psát několikrát stejnou továrničku je špatné a cpát mnoho továrniček do BasePresenteru taky není čisté řešení
  • v Nette mi chybělo jednoduché přiřazení šablony formuláře přímo v definici formu (bez nutnosti vytvářet komponentu)
  • ač se jedná o dvě rozdílné věci, presentuji je dohromady, protože spolu často souvisí

Inspirace:

Řešení:

MAGICKÁ SUPER TOVÁRNIČKA v Basepresentru

  • nejedná se o nic nového, jen umí zpracovat i potomky třídy Nette Form (nadělat z nich komponenty)

MAGICKÁ UNIVERZÁLNÍ KOMPONENTA NA FORMULÁŘE

  • umí vytvořit komponentu z Formu
  • magicky dohledává šablony podle pravidel(*)
  • umí pohledy komponent
  • nepoužívá se samostatně, ale v továrničkách

(*) Pravidla dohledání šablon:

Všechny magicky přiřazené šablony se hledají ve stejném adresáři kde je soubor se definicí formuláře (XxxForm.php)

1)
pokud je definován pohled, použije se šablona ve tvaru <view>.latte, když se nenajde, vyhazuje se výjimka

2)

  • pokud není definován pohled, použije se šablona která je definována ve formuláři ($form->template). Omezení adresáře zde neplatí.
  • pokud není šablona ve formuláři nastavená, použije se šablona ve tvaru <className.latte> (např. xxx.latte) v adresáři formuláře

3)
když stále nemáme odpovídající šablonu, tak se použije DefaultRenderer


Upozornění:

Pohled {control xxx:default} je obyčejný pohled a zpracovává se podle pravidel pro pohledy (šablona ‚default.latte‘, jinak výjimka).

Naopak při zápisu {control xxx} se použije buď šablona ‚xxx.latte‘, nebo DefaultRenderer. Případná šablona ‚default.latte‘ se ignoruje.

Editoval Šaman (30. 4. 2011 17:21)

Ondřej Mirtes
Člen | 1536
+
0
-

Apríla už bylo, ne?

Magické super ultra mega továrničky nejsou dobrý nápad. Pokud budeš mít v systému nějakou třídu, která v konstruktoru vykonává něco ošklivého, dovolíš takto uživateli, aby ji spustil.

Není to prostě dobrý nápad, dáváš tím uživateli obrovskou moc.

Martin
Člen | 171
+
0
-

Ondřej Mirtes napsal(a):

Apríla už bylo, ne?

Magické super ultra mega továrničky nejsou dobrý nápad. Pokud budeš mít v systému nějakou třídu, která v konstruktoru vykonává něco ošklivého, dovolíš takto uživateli, aby ji spustil.

Není to prostě dobrý nápad, dáváš tím uživateli obrovskou moc.

Vysvětli, prosím.

Honza Marek
Člen | 1664
+
0
-

Cožpak o to, super mega továrnička je nějaká potřeba. Právě aby nemuselo být milion createComponentBlabla v BasePresenteru. Ale dovedl bych si to představit třeba tak, že by to hledalo jen v patřičně otagovaných službách z DI containeru, to by bylo bezpečnější.

Vysvětli, prosím.

class Zlo
{
	public function __construct()
	{
		vsechnoZnic();
	}
}
{control zlo}
Ondřej Mirtes
Člen | 1536
+
0
-

Za {control zlo} v šabloně by sis mohl sám, ale strčit ?do=zlo-signal do URL může každý.

Prostě tím dovoluješ uživateli, aby instancioval jakoukoli tvoji třídu. Nehledě na to, že v továrničkách obvykle ještě něco do komponenty donastavuješ, osobně bych pro ni měl jen minimální využití.

Martin
Člen | 171
+
0
-

V zásadě problém chápu. Ale při pohledu na zveřejněný kód mi nějak uniká, jak ?do=zlo-signal může vyvolat popisované chování, když se dohledává jen metoda render... a ne signal... . Můžete to vysvětlit?

Šaman
Člen | 2632
+
0
-

Tak po nějaké době používání k tomu mohu napsat toto:

  1. MAGICKÁ SUPER TOVÁRNIČKA v Basepresentru

Není nutná, ušetří mě sice metod createComponentXxx, ale jen pokud v nich nic nenastavuji. Takže na vytvářecí formuláře se to použít dá, na editační už ne (v továrničce je nutné nastavit editované hodnoty).
Řekl bych, že od tohoto v příští aplikaci upustím (nebo možná refaktoruji už tuto), protože neexistence metody createComponentXxx je moc WTF. Člověk si zvykne že tato továrnička neexistuje a tak ji nehledá (ani když existuje třeba v předkovi našeho presenteru a přepíše ji znovu a pak se to blbě ladí.)

Ondrovo argumenty mě nedošly, ale má pravdu a je to další hřebíček do SuperMegaMagicTováren.

  1. MAGICKÁ UNIVERZÁLNÍ KOMPONENTA (NEJEN) NA FORMULÁŘE

Super věc, vpodstatě se jedná o upravenou Lookout Control a její potomek upravený tak, aby zvládl vykreslit předaný formulář podle šablony. Je to tedy předek komponent který je naučí dohledat svoji šablonu. Jenom si ještě nejsem úplně jistý konktétním chováním – šablona default.latte působí dost WTF v případě, že v adresáři už existující komponenty vytvořím novou. Řešením je buď každou komponentu do samostatného adresáře, nebo nepoužívat defaultně pohled default (tak, jak je to vyřešené výše. Zkoušel jsem i jiné nastavení, viz, LookoutControl, ale několikrát jsem narazil na neočekávané chování.)

Jan Tvrdík
Nette guru | 2595
+
0
-

Martin wrote:

Ale při pohledu na zveřejněný kód mi nějak uniká, jak ?do=zlo-signal může vyvolat popisované chování, když se dohledává jen metoda render... a ne signal... . Můžete to vysvětlit?

Pokud existuje param do, tak Nette se pokusí sehnat komponentu zlo a spustit na ní signál signal. A právě to hledání komponenty zlo spustí createComponent('zlo'). Ze stejného důvodu nesmí metoda createComponent vyhazovat výjimky v případě, že nedokáže danou komponentu nalézt.

_Martin_
Generous Backer | 679
+
0
-

@Šaman: Jen taková poznámka k best practice: plnění formuláře daty nepatří do jeho továrny. Vhodným místem je action metoda, případně metoda render.