Výhody aktivních šablon

Školení, která pořádám

Většina šablonovacích systémů je pasivních – to znamená, že program musí nejprve získat data a následně je předat šabloně. Opakem jsou aktivní šablony – ty se nejprve začnou zobrazovat a teprve když potřebují, tak si získají data.

Hlavní výhoda aktivních šablon spočívá v tom, že se začnou posílat a zobrazovat v prohlížeči ještě před tím, než se získají všechna data. Pokud je získání některých dat časově náročné, tak to má zásadní vliv na prožitek uživatele, protože od serveru ihned dostane nějakou odezvu (a průběžně ji získává tak, jak se data načítají), takže má dojem, že server pracuje rychle (i když získání dat trvá v obou případech stejně).

Pasivní šablona
Aktivní šablona
Legenda

Situace s aktivními šablonami je ve skutečnosti ještě lepší, protože když se stránka odesílá do prohlížeče a tam zobrazuje, tak server už může získávat další data. Uživatel získá rychleji nejen první odezvu, ale stránka se zobrazí rychleji i celkově.

Aktivní šablona ve skutečnosti

Aktivní šablony navíc nemusí držet všechna načtená data v paměti, takže jsou šetrnější.

Implementace aktivních šablon

U jednoduchých šablonovacích systémů, které používají pro předání dat pole (jako třeba HTMLtmpl), lze místo pole předat objekt implementující rozhraní ArrayAccess. Ten může v metodě offsetGet získat data až když to je potřeba.

U šablonovacích systémů používajících pro předání dat objekt lze ve třídě pomocí přetěžování zřídit virtuální vlastnosti, které se opět načtou až v případě nutnosti. Na rozdíl od předchozího přístupu to dovoluje předem načíst data, jejichž získání je téměř zadarmo (např. data z formuláře).

Ideální šablonovací systém by měl dovolovat oba přístupy – buď získat hodnotu proměnné nebo zavolat funkci vracející data. Jenom je škoda, že PHP nemá na rozdíl např. od JavaScriptu zvláštní datový typ pro funkce. Funkce is_callable se použít nedá, protože vrátí true na všechny řetězce, které odpovídají názvu nějaké funkce, a také na všechna dvouprvková pole, která v prvku s indexem 0 obsahují název třídy nebo objekt a v prvku s indexem 1 nějakou jeho metodu. V PHP 5.3 se alespoň pro detekci anonymních funkcí bude dát použít detekce instance třídy Closure.

Jakub Vrána, Seznámení s oblastí, 23.3.2009, diskuse: 31 (nové: 0)

Diskuse

fos4:

Ve firmě používáme XSLT a neumím si představit že bychom měli něco jiného. Vždy, když se podívám na na něco jiného, na ty ty různé značky apod. tak nechápu jak se v tom může někdo vyznat.

Výhodou XSLT je, že programátor pošle XML a kodér si ho libovolně upraví, pokud chce kodér použít data která v XML nemá (např. jaký banner v této kategorii zobrazím a komu) stačí když použije php:function() nebo php:functionString().

Nevýhodou je XSLT transformace která trvá poměrně dlouho a do té doby není co posílat na výstup. Celý proces jsme zrychlili když jsme XML přestali rvát do arrajů, stringů a začali používat DOM XML.

ikona Jakub Vrána OpenID:

Problém je, že většina kodérů XSLT nezná. Navíc to podle mě na naučení není úplně jednoduchý jazyk, rozhodně složitější než pár značek šablon (které se navíc můžou zapisovat stejně jako PHP, které bývá kodérům přinejmenším povědomé).

Náhodou jsem narazil na ještě jeden koncept: http://www.sitepoint.com/blogs/2008/09/25/dom-vs-template/. Šablona se vytvoří bez jakýchkoliv konstrukcí a data, podmínky a cykly se tam injectují přes DOM. Šablona je pak čisté HTML, které se dá ladit i bez šablonovacího systému.

<?php
$t
= new Domling('<p class="hello"></p>');
$t->capture('hello')->bind("Hello World");
echo
$t->render();
?>

fos4:

To že ho neznají je velká škoda, přičemž mne připadá ze všech možností nejlepší, ale třeba jsem na něj až moc fixovaný :-)

Navíc mně to přijde jako míchání dvou vrstev, které by měli být oddělené.

srigi:

Tak tento DOM pritup vypada fantasticky. Umoznuje to zachovat "Lorem ispum dummy" v sablone od kodera? Ak ano, tak by to bola uplna spicka.

ikona Jakub Vrána OpenID:

Ano, obsah elementu se nahradí, takže tam lze nechat ukázkové texty. Ale zdá se mi to trochu nebezpečné, protože pokud by se náhrada (třeba kvůli dodatečně přidané podmínce) za určitých okolností neprovedla, tak to zůstane i v ostrém výstupu.

Dvorak:

Už jsem vyděl mnoho programovacích jazyků, ale XSLT je zcela jistě to nejhorší, co jsem viděl.
Zapisovat konstrukce jazyka v XML je ten nejhořší nápad. Navíc, všechno je tam hrozně kostrbaté, proměnné, cykly, práce s řetězci, vložit jeden znak mezery do výstupu je na celý řádek, atd, atd.

Dušan Medlín:

Pane Dvořák, nezlobte se na mě ale XSLT jste viděl asi někde z pendolina, zkoušel jsem více značkovacích jazyků a XSLT je jednoznačný vítěz. Ano má svá omezení - nejhorší omezení je že proměná je spíše kontantou, ale při troše toho fištrónu se to dá obejít. A že to je kostrbaté - nevím co je kostrbatého na absolutním oddělení PHP(ASP ...) od formátování výstupu ?

Ad Jakub Vrána : XSLT není nijak složité, základy se lze naučit za jedno odpoledne - ono hodně záleží na editoru a zde nelze než pochválit pana Fialu za PSPad.

Dvorak:

Milý Dušane, XSLT není značkovací jazyk. Já řeknu, že XSLT je jako programovací jazyk kostrbaté, a ty na to něco o oddělení PHP od výstupu - tomu vážně nerozumím. Měl by jsi méně jezdit tím pendolínem.
P.S. v XSLT dělám už dlouho, např, složité transformace XML dat jejichž schéma má 400kB, takže si troufám tvrdit, že už o tom něco vím.

Dušan Medlín:

Jop trochu mi ujela ruka, omlouvám se, ale mám XSLT rád :) Pro mé účely je plně vyhovující.

ikona Miloslav Ponkrác:

Naprosto souhlasím. Myslím si, že XSLT je opravdu něco, co bych nechtěl na tyto účely moc používat.

fos4:

A místo toho budeme používat různé php + html šablony, abychom měli aplikační a prezenční logiku pěkně v sobě.

V XSLT dělám též dlouho a také složité transformace a neumím si představit že bych tyto složitosti měl dělat pomocí smartů za předpokladu zachování přehlednosti.

ikona Miloslav Ponkrác:

Pane, vzpamatujte se, prosím. Oddělení aplikační a prezentační logiky můžete řešit miliónem způsobů.

Mícháte do sebe dvě nesouvisející věci - oddělení aplikační a prezentační logiky a XSLT. To, že nikdo nepoužije XSLT neznamená, že nemá oddělenou aplikační a prezentační logiku. Už je to jasné?

matak:

aktivní šablony podle mne právě porušují to oddělení aplikační logiky a prezentační logiky, což považuji za léta praxe za hodně důležité

1. příklad aplikace kde je to takový problém, že se stránka nevykresluje najednou? chápu že může trvat natažení obrázků a grafiky, ale natažení dat? jak to může trvat? není něco špatně? tady si myslím, že je úplně jedno co se vykreslí na obrazovku ale dokud nejsou natažena data, tedy to co návštěvníka zajímá, tak je to stejně k ničemu. pokud je aplikace založena na datech a zákazník na ně musí čekat, spíš bych čekal že uteče než si bude prohlížet vykreslování obrazovky
2. myslel jsem, že šablony jsou od toho, aby oddělovali logiku od prezentace
3. problém bývá právě v určitých chybách, kdy se stránka rozpadne místo aby informovala v čitelném okně mimo design co se děje a kdy to půjde
4. xslt nebo smarty jsem na mnoha projektech už používal, ale pokud si mohu vybrat sázím na disciplinovanost programátora a neznalost grafika, šablona má být pro grafika, a tady bych spíš počítal s tím, že grafici se mění a umí xhtml a css, případně xslt, ale těžko od nich chtít víc, pravda kodér je něco jiného, ale nerad vidím, když grafik zasahují do funkčnosti jakýchkoli funkcí, klasicky přesune nějakou funkci před nebo za blok co používá její výstup, těžko mu to vysvětlovat

ikona karf:

"2. myslel jsem, že šablony jsou od toho, aby oddělovali logiku od prezentace"

Já si myslím, že jsou na to, aby oddělovaly logiku prezentační od logiky aplikační. V tom je drobný, ale ne nepodstatný rozdíl. I prezentační vrstva má svou logiku. "Aktivnost" či "pasivnost" šablon podle mého názoru nesouvisí s tím, jak striktně je v nich oddělena prezentační logika od aplikační. Dále také zastávám názor, že to nemusí být nutně znamenat oddělení PHP od HTML.

"...a tady bych spíš počítal s tím, že grafici se mění a umí xhtml a css, případně xslt..."

Na jakéže to planetě se tento druh grafiků vyskytuje? :)

matak:

Sorry, ujela mi asi ruka.

"...a tady bych spíš počítal s tím, že grafici se mění a umí xhtml a css, případně xslt..."

1. chtěl jsem říct, že grafici se nemění, a většinou grafik=kodér, myslete si o tom co chcete, ale z mé zkušenosti to tak bývá (byť třeba nemělo být). A tím chci říct, že lze jen stěží od nich něco čekat navíc než css + xhtml, tedy často se mi stane, že v nějakém cyklu jen naplním proměnnou, kterou má zpracovávat další blok, např. proměnná co si pamatuje poslední lichý řádek, aby další blok vypisující jiná data začal na sudém, klasicky mi to grafik přehodí a pak se diví proč mu to dva řádky vypíše šedivě a před tím to šlo (tohle považuji za prezentační logiku, tomu se asi nikdo nevyhne)

... 2. Jak push, tak pull šablony samozřejmě stále oddělují prezentační logiku od aplikační. Jde jen o to, aby volané funkce neprováděly žádné aplikační operace, ale jen vracely data. Navíc pokud šablona přijímá data v objektu nebo poli, tak se to pomocí metod popsaných v článku dá stejně přeložit na volání metody. ...

takže tvrdíš, že např. anketa by se měla načítat až v šabloně? tím chápeš aktivní šablony? já bych postupoval tak, že buď se anketa načte a ty data má a v šabloně si to ověřím a buď ji zobrazím nebo ne
každopádně dobře tak příklad ankety, např. na jednom mém projektu celý web sleduje, jestli se někde neobjevil tag, nebo jméno hráče a pokud ano, připojí k němu vyskakovací bublinu s jeho statistikami, ovšem to předpokládá, že už existuje nějaký zásobník hráčů v opačném případě bych na základě takového výskytu musel neustále znovu pokládat dotazy do dtb a zjišťovat tyto data, existuje ještě jeden přístup jak to řešit, celou stránku si načtu do bufferu a pak teprve parsuji, zjišťuji tyto statistiky a nahrazuji html kód podle toho co vytáhnu z dtb, obojí ale jestli si rozumíme jde proti tvým aktivním šablonám

závěrem si myslím, že je maximálně vhodné oddělit zobrazení od načítání a práci s daty,

máš nějaký příklad stránky, kde data opravdu brzdí zobrazování stránky uživateli?

máš nějaký praktický příklad takové šablony?

ikona Jakub Vrána OpenID:

1. I kdyby natažení stránky trvalo třeba dvě sekundy, což je pro uživatele přijatelné, tak je pořád lepší, když první výsledek dostanou za půl sekundy a celou stránku za sekundu a půl.

2. Jak push, tak pull šablony samozřejmě stále oddělují prezentační logiku od aplikační. Jde jen o to, aby volané funkce neprováděly žádné aplikační operace, ale jen vracely data. Navíc pokud šablona přijímá data v objektu nebo poli, tak se to pomocí metod popsaných v článku dá stejně přeložit na volání metody.

3. Souhlasím, že nenačtení některých dat může být problém. V různých případech se ale řeší různě. Kupříkladu když se podaří načíst článek a diskuzi a nepodaří se načíst anketu, má to způsobit fatální chybu celé stránky? Neřekl bych. Ideální je tedy nezbytná data napushovat a volitelná pullnout.

ikona Martin Malý:

XSLT je použitelné tam, kde jsou hlavní data (data-centric). U webových aplikací je však hlavní kód, ne data (code-centric). Na transformování dat je to dobré, ale psát v tom HTML UI je za trest, tam se klasické šablonovací systémy (které dostatečně oddělí PHP od HTML) hodí mnohem líp.

ikona Martin Malý:

"Výhodou XSLT je, že programátor pošle XML a kodér si ho libovolně upraví, pokud chce kodér použít data která v XML nemá (např. jaký banner v této kategorii zobrazím a komu) stačí když použije php:function() nebo php:functionString()." - hm. Takže máme krásné míchání aplikační a prezentační logiky jak když vyšije. :) Navíc - zkuste se podívat na jakoukoli moderní webovou aplikaci a změřit si, kolik je tam XML dat a kolik je tam HTML kódu...

lukas ;):

Ja bohuzel mam s XSLT taky spatnou zkusenost, pracoval jsem s nim skoro rok na celkem velkem webu (autoweb.cz) a spousta veci je tam silene kostrbata. Zkousel jsem spoustu jinych systemu (smarty, ciste php a dalsi) a podle me je to jednodussi a ucelnejsi. Ted delam v Djangu a naprosta spokojenost, sablonovaci system je tam celkem jednoduchy, ale dobre vymysleny a rozsiritelny (a v zakladu pasivni, ale neni problem doplnit aktivni prvky). Kdyz uz probirate moznost postupneho nacitani, tak idealni by byl system, kde by server vratil jen sablonu treba se zakladnim (a podstatnym) obsahem a ostatni (sidebary, reklamy, navigace a dalsi) by se nactlo pres ajax dynamicky ;)

ikona Jakub Vrána OpenID:

U reklam se tento koncept už naštěstí používá – v HTML jsou na pozici reklam jen prázdné DIVy a reklama se do nich vloží až na konci stránky. U ostatních částí stránky by to bylo nešťastné (nefunkčnost bez JS, více požadavků na server a tím pomalejší odezva) – lepší mi přijde uvést kód v takovém pořadí, v jakém chci, aby se postupně zobrazoval uživateli a rozmístění vyřešit styly (jako třeba na tomto blogu).

lukas ;):

no, v pripade dobre vyresenych sablon by ajax tahal z cache prohlizece a vlastne by usetril praci serveru. Ale uznavam, ze by bylo pomerne slozite sladit to, aby to dobre fungovalo a samozrejme udelat alternativu pro prohlizece bez JS, to by asi nebyl problem...

Jan Tvrdík:

Za největší problém aktivních šablon považuji komplikovanou možnost reakce pokud dojde uprostřed renderování k chybě. Uživatel pak vidí jen kus HTML a rozpadný web.

ikona karf:

Zdá se mi, že se v článku míchají dvě ne úplně související věci: push/pull šablony a posílání výstupu "on the fly". To, že použiji pull šablony (šablona si tahá potřebná data během zpracování) ještě nemusí znamenat, že se výstup posílá rovnou ven. Pokud se stránka generuje rozumnou dobu, pak v tom není zas tak zásadní rozdíl.

Já např. používám šablony, kterým předám objekt příslušné komponenty, šablona si pak tahá data voláním jejích veřejných metod. Zároveň však jde výstup do output bufferu a jednotlivé šablony se pak skládají dohromady "nelineárně".

ikona Jakub Vrána OpenID:

Je to pravda, článek skutečně předpokládá output buffering vypnutý nebo nastavený na omezenou velikost (např. 4 KB). Myšlenka je ta, že s pasivními (push) šablonami nelze uživatele seznámit s částečným výsledkem před načtením všech dat a nelze zkrátit celkovou dobu načtení, s aktivními (pull) šablonami to jde.

Pokud je zapnutý output buffering na celou stránku, tak mají aktivní šablony stejný graf jako pasivní.

ikona v6ak:

No ono to má i určité nevýhody. Není možné se při chybě včas rozhodnout o poslání 404 nebo pětistovky (podle případu).

ikona Jakub Vrána OpenID:

Jak už jsem psal – data, jejichž absence by měla způsobit fatální chybu, je možné pushnout, ostatní pullnout.

ikona v6ak:

No jo, ale většinou nejdéle trvá načítání těch dat, která jsou hlavní a kvůli kterým by se měl poslat chybový kód.

ikona Jakub Vrána OpenID:

Neřekl bych, že většinou. Třeba načíst článek je jeden dotaz do databáze podle unikátního klíče vracející jeden řádek, ale načíst všechny jeho diskuse, ankety a další závislé objekty už je složitější a datově náročnější. A to už jsou podle mě postradatelné objekty. A takovéto schéma je podle mě na většině stránek – jeden hlavní objekt, který se snadno získá a k tomu spousta dalších objektů, jejichž získání je náročnější. Ten hlavní objekt je navíc obvykle hned na začátku.

Platí to i u výpisů – když chci třeba seznam článků, tak jejich nadpis a perex je nezbytný (to zařídí jeden rychlý dotaz), ale počet diskusních příspěvků volitelný. Když se pro získání počtu použije Konstantní počet dotazů popsaný na http://php.vrana.cz/srovnani-dotazu-do-zavislych-tabulek.php, tak mi nic nebrání si tento počet pullnout.

ic:

na tom něco bude... třeba na to jestli má nebo nemá vrátit chybu 404 může server přijít hned na začátku takže tam to takový problém není, ale u jiných chyb, nebo pokud dojde k nějaké chybě scriptu v průběhu načítání a člověk by jí chtěl ošetřit přítomností statusu 503 tak na to už bude asi pozdě, pokud už část kódu bude vypsána.

ikona david@grudl.com:

Sice pod "aktivní šablonou" si představuji něco malinko jiného a článek bych spíš napsal "výhody lazy loadingu", ale jinak je pravda, že lazy loading může mít blahodárný vliv na prožitek uživatele i paměťovou náročnost aplikace.

Příklad, jak lze podobného výsledku dosáhnout s dibi, jsem blognul henkaj http://phpfashion.com/mvc-paradox-a-jak-jej-resit

Miloš Brecher:

Postup popsaný u aktivní šablony - sama si tahá data podle potřeby je dle mého názoru jediný možný pokud nemá prezenční vrstva přebírat roli modelové vrstvy. Představme si, že komponenty vykreslované v šabloně závisí na datech které nasosá model - např. u zakázky která je označena jako VIP se bude vypisovat přehled kritických dat (komunikace s klientem?), které se u jiné zakázky nevypisuje.

Aby presenter dopředu věděl co bude šablona vykreslovat a co ne, musel by si data stáhnout a analyzovat - stejná data potom bude stahovat a analyzovat i šablona. Presenter by se o detaily vykreslování starat neměl. Je samozřejmě otázka, kde stanovit hranici mezi kompetencemi presenteru a šablony - mě se osvědčil postup aktivní šablony, kde na základě jedněch dat šablona vykreslí cosi a analýzou dat dotáhne dle potřeby další data pokud se mají vykreslit. Pokud se nemají vykreslit tak je nestahuje vůbec.

Presenter by měl samozřejmě dodat pouze odkazy na příslušné modelové objekty, které data dodají na pokyn šablony. Asi šabloně nepřísluší aby si sama vyráběla modelové objekty. Je to jak o principu lazy loadingu (jak píše David Grudl), tak i o principu kompetencí mezi presenterem (prezenční vrstvou) a šablonou.

Dynamicky dotahovaná data mohou obsahovat aktivní komponenty s funkcí - např formuláře, tlačítka apod... Ty by měl presenter zaregistrovat a měl by o nich mít vědomost. Zde by aktivní šablona zpětně měla presenteru dodat odkazy na tyto objekty aby je zaregistroval. Jinak by se presenter zcela obešel a aktivní šablona by si vyráběla komponenty a zpracovávala jejich akce ve spolupráci s modelem.

Přitom si nemyslím, že by situace, kdy šablona rozhoduje o tom které a kolik komponent bude vykresleno a do presenteru "injektováno" porušovala MVC koncept. Kompetence vrstev odděleny jsou a z logiky věci je jasné, že např. o tom kolik a jakých tlačítek se vypíše do každého řádku tabulky rozhodují data a ty prochází šablona. Presenter by měl zachytit nějaké fatální stavy dat - kdy data nedávají smysl (např. zakázka neexistuje) a nějak to ošetřit aby toto nemusel už aktivní šablona dělat.

Aktivní šablona je tak koncept, bez něhož se neobejdeme u logicky složitějších webových aplikací, kdy se nevypisují jenom články na blogu nebo vypůjčené knížky z knihovny.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.