Before print aneb helper always

joseff
Člen | 233
+
0
-

Lze nějak zavolat funkci vždy když se něco vypisuje, něco jako {$anyValue|h} ale bez toho |h ale abych to nemusel vždy a všude psát???

Editoval joseff (22. 3. 2021 6:29)

dakur
Člen | 493
+
0
-

@joseff Můžeš sdílet i důvod, proč bys to chtěl dělat? Mně přijde, že na tom něco neštymuje a že by to šlo vyřešit jinak.

Šlo by to ale určitě třeba poděděním Latte engine nebo tak něco, zkrátka zásahem do samotné kompilace šablon.

Editoval dakur (22. 3. 2021 9:12)

David Matějka
Moderator | 6445
+
0
-

Ahoj, o výpis proměnné se stará tohle makro, které je registrované pod názvem = (latte pak umožnuje to rovnáse v některých případech vynechat). Takže bude stačit overridnout to makro = vlastním. Ale také by mě zajímal důvod.

Milo
Nette Core | 1283
+
+1
-

Já bych jeden chabý důvod měl a trochu ho tu rozepíšu.

Value objekty, dejme tomu osobu. V šabloně musíš psát {$person->fullName} namísto krátkého {$person}. Jasně, no big deal. Ale pak to budeš chtít změnit třeba na výpis s akademickými tituly, anebo na popover s bližší informací o osobě.

Řeším to občas metodami ve stylu Person::toHtml(): Html a v šabloně {$person?->toHtml()} (mimochodem, existence ?-> tomuhle řešení hodně pomáhá). Výhodou je, že když smažeš třídu Person, zmizí i metoda toHtml(), která nehnije nadeklarovaná někde jinde. Nevýhodou je, že do value objektu zatáhneš informaci o tom, jak vykreslit HTML.

S @DavidGrudl jsem se jednou bavil o možnosti tohle přeskočit a zavést možnost deklarace jak daný typ vykreslit. Pseudokódem:

$latte->addTypeRenderer(Person::class, function (Person $person) {
	return $person->fullName;
});

Zní to hezky, ale potíž je s tím, že by se musela dělat typová detekce u každé vykreslované proměnné, což by mělo velký dopad na výkon. A tam jsme diskuzi skončili.

Dá se to emulovat nějakým obecným filtrem:

$latte->addFilter('toHtml', function (?object $v) {
	if ($v instanceof Person) {
		...
	}
	...
});

a v šabloně {$person|toHtml} což je snesitelné. Při refaktoringu CSS/JS je to hezky pohromadě. A filtr může mít i závislosti. Například nepřihlášenému zobrazí jen jméno osoby, přihlášenému navíc popover s telefonem.

dakur
Člen | 493
+
0
-

A proč bys měl do šablony vůbec předávat celý objekt Person, pokud z něho chceš renderovat jen jméno? To je lepší předat jen to jméno jako string a tento problém vůbec nemáš, ne?

Kamil Valenta
Člen | 815
+
0
-

Milo napsal(a):

Value objekty, dejme tomu osobu. V šabloně musíš psát {$person->fullName} namísto krátkého {$person}.

{control "person-$personId"}

?

Jak se má vypsat detail osoby si pak řeším v šabloně komponenty, netahám si html nikam jinam…

David Grudl
Nette Core | 8218
+
0
-

Tak typová detekce není asi zase tak velký výkonnostní problém. Nebo objekty mohou rovnou implementovat nějaký interface, třeba Latte\HtmlStringable nebo tak něco.

Milo
Nette Core | 1283
+
0
-

dakur napsal(a):

A proč bys měl do šablony vůbec předávat celý objekt Person, pokud z něho chceš renderovat jen jméno? To je lepší předat jen to jméno jako string a tento problém vůbec nemáš, ne?

Jak jsem psal – jednoho dne se dojde k tomu, že se to má vykreslovat jinak a najednou se to musí změnit na X místech. Píšu hodně intraweby/administrátorská rozhraní a v jednom vypisuji osobu na 30+ místech. To není zanedbatelný čas úprav.

Milo
Nette Core | 1283
+
0
-

Kamil Valenta napsal(a):

Milo napsal(a):

Value objekty, dejme tomu osobu. V šabloně musíš psát {$person->fullName} namísto krátkého {$person}.

{control "person-$personId"}

?

Jak se má vypsat detail osoby si pak řeším v šabloně komponenty, netahám si html nikam jinam…

Má to své použití, ale často by to byl overengeneering. $personId se musí znovu resolvovat na entitu, což je to nejmenší. S každým value objektem musí vzniknout jeho renderer komponenta a její továrna. A to často jen proto, aby se například místnost vykreslila jako A-231.

Milo
Nette Core | 1283
+
0
-

David Grudl napsal(a):

Tak typová detekce není asi zase tak velký výkonnostní problém. Nebo objekty mohou rovnou implementovat nějaký interface, třeba Latte\HtmlStringable nebo tak něco.

To Latte\HtmlStringable je lákavé, ale pořád jsem na vážkách, jestli to ten objekt má umět, nebo ne. Narazil jsem třeba ve vícejazyčné aplikaci, kdy měl být popover podle jazyka aplikace. Vznikla tak další závislost.

David Grudl
Nette Core | 8218
+
0
-

No tak tam dát normálně test na objekt. Tu diskusi si nepamatuju :-) ale jako nevidím v tom výkonnostní problém, dá se to udělat efektivně.