Nápad na práci s Latte pomocí „vizuálních komponent“
- Michal III
- Člen | 83
Kdybych pracoval více na frontendu – a tedy se šablonami – chtěl
bych si vytvářet malinké vizuální komponenty, které bych skládal do
velkých celků. Chtěl bych si třeba nadefinovat vzhled submit tlačítek a
mít je konzistentní v celé aplikaci. Chtěl bych být odstíněn od jmen
*.latte
souborů a adresářové struktury, chtěl bych pracovat se
jmennými prostory.
<n:base:submitButton caption>
<p class="foo"><input type="submit" class="bar" value="{$caption}"/></p>
</n:base:submitButton>
{* Párové tagy by komponentu definovaly, pomocí nepárové tagu by se komponenta používala. *}
<n:base:address address>
<p>Ulice: {$address->street}</p>
<p>ČP: {$address->houseNumber}</p>
<p>...</p>
</n:base:address>
{* ------- *}
<n:company:detail company>
<p>Název společnosti: {$company->name}</p>
<n:base:address address={$company->address}/>
</n:company:detail>
{* ------- *}
<h1>Detail firmy</h1>
<n:company:detail company={$company}/>
{* Se jmennými prostory potom například takto: *}
<n: namespace="company"/>
<n: use="base:address"/>
<n: use="base:submitButton"/>
{* <n: namespace="company" use="base:address" use="base:submitButton"/> *}
{* a pak tedy jen *}
<n:detail .../> {* company:detail *}
<n:submitButton .../> {* base:submitButton *}
Nechtěl bych tedy řešit, v jakých souborech jsou komponenty definovány, ale v jakých jmenných prostorech jsou definovány. (Mohly by se tedy definovat i pomocí PHP pro širší možnosti.)
Kdybych chtěl vykreslovat formulář, nechtěl bych to řešit přes
nějaký defaultní renderer, který bych, pokud by nevykreslil
formulář podle mých sofistikovanějších představ, musel vykreslovat
ručně (a na polovině z nich zapomenout vypisovat
$form->errors
). Chtěl bych si nadefinovat komponenty pro
nějaké typické výchozí způsoby (inline formuláře, do tabulky, labely
vs pouze placeholdery) a mít možnost nějak elegantně řešit drobné
rozdíly.
<n:company:form:employee form>
<p><n:base:input value={$form['firstName']}/> <n:base:input value={$form['lastName']}/></p>
{* dále už po řádcích *}
<n:base:form form={$form} exclude={['firstName', 'lastName']}/>
</n:company:form:company>
Co si o tom myslíte?
- Michal III
- Člen | 83
Není to pouze o formulářích, těch se to týká pouze tím způsobem,
že pomocí těchto „vizuálních komponent“ bychom si základní vzhled
formulářů definovali v šabloně pomocí Latte a ne takto.
Navíc bychom už v šabloně viděli, jakým způsobem je formulář
vykreslován, a mohli bychom se až v šabloně rozhodnout, jakým způsobem ho
chceme vykreslit (To je trochu ekvivalent toho poděděného, který bych
osobně řešil spíše nějakou funkcí, která nám tomu formuláři nastaví
požadovaný renderer –
$form = new Form; $this->setMyRenderer($form);
). Řekne nám
trochu víc toto:
<n:base:form form="addEmployee"/>
než toto:
{control addEmployee}
Ale to je opravdu jen okrajová část tohoto návrhu. Když jsem narazil na toto vlákno, nelíbilo se mi z navrhovaných řešení ani jedno. Představoval bych si, že by v aplikaci těchto komponent bylo hodně a neumím si představit, že by pro každý znovupoužitelný odkaz/tlačítko/… vznikala samostatná komponenta (tedy komponenta + interface pro DI + registrace v configu + továrnička např. v presenteru).
A „includování“ nějakého bloku… kde by měl být tento blok
definován? Buď někde v nadřazeném @layout
, kde podle mě
nemá co dělat, nebo v nějakém jiném souboru a v tu chvíli bych se musel
starat o to, jakým způsobem ho do šablony „includuju“ (specifikace cesty
k souboru).
Třeba mi něco uniká, ale můj návrh se mi zdál docela zajímavý. Když má Latte n:atributy, proč by nemohlo mít n:tagy.
- Myiyk
- Člen | 321
Chápu co myslíš
Jestli chceš podobným způsobem pracovat s aktuálním nette, můžeš si definovat blok a potom ho používat.
Soubor components.latte
{define button}
<a class="....." href="{$link}">{$text}</a>
{/define}
V šabloně, kde to chceš použít:
{include 'components.latte'}{* soubor kde jsou definice *}
{include button, link => "...", text => "abc"}
edit: aha, sorry, nevšiml jsem si že tohle nechceš
Editoval Myiyk (4. 9. 2014 20:18)
- Myiyk
- Člen | 321
Při použití párového tagu by bylo docela nepraktické psát ten název
dvakrát (začátek a konec).
Při definici bloku se taky jeho název nepíše dvakrát.
Spíš bych to viděl na něco jako
<n:base:address>
<p>...</p>
</n:tag>
... nebo ..
</n:block>
A nějak nechápu, proč do toho tagu psát proměnné, které se budou používat. (Bloky to taky nepotřebujou)
Tenhle nápad se mi docela zamlouvá, a nebylo by snad tak složité to naprogramovat, když to má úplně stejnou funkčnost jako bloky, ale pouze s jinou syntaxí. Takže by takováhle html syntaxe mohla spolupracovat s běznými bloky.
A v @layout by šlo použít
<n:content />
- Michal III
- Člen | 83
ad párové tagy: Zas až tak nepraktické to není (editory
umí vygenerovat z názvu celý párový tag – např. Emmet). Usnadňuje to
orientaci a odpovídá to xml specifikaci. Nicméně na této drobnosti by asi
zas tolik nezáleželo. O tom bych diskutoval, až by byla přijata ta
základní myšlenka. Asi bych ani k takové zkratce nic neměl – teoreticky
by se to mohlo týkat všech tagů v Latte (např.
<div><p></></>
), já osobně bych to ale
nepoužíval.
ad specifikace atributů: Opět je to už víceméně detail, nicméně díky tomu by bylo od pohledu hned jasné, na čem ten blok závisí. Mohly by se specifikovat povinné a nepovinné atributy (nepovinné by měli např. určenou výchozí hodnotu). Dokonce by si atributy mohly klást podmínky na určité typy proměnné (array, DateTime…).
Ovšem jako hlavní přínos vidím v použití jmenných prostorů a
v tom, že bych se nemusel starat o vkládání hledání cesty, kde jsou ty
které bloky definovány. Aktuální bloky v Latte fungují velice dobře co se
týče dědičnosti (např. určení výchozího obsahu v @layout
).
Tyto vizuální komponenty by byly zase pro kompozici.