perunTPL - šablónový systém pre PHP
Nie som ortodoxný zástanca MVC modelu, myslím si, že pre potreby webu nie je vhodné jeho absolútne dodržiavanie. Obzvlášť veľké problémy dokáže narobiť striktné oddelovanie modelu (databáza) a controlleru (aplikačná logika PHP). Vo výsledku máte programátorsky krásnu a čistú aplikáciu, ktorá však pokojne urobí 500, 1000, 1500 dotazov na databázu pre zobrazenie jednej stránky, kde by ich inak stačilo 20 (to je reálny prípad niekoľkých webov, s ktorými som prišiel do styku). A veľa dotazov na databázu, to je niečo, čo vám pri vyššej návštevnosti zabije server.
Samostatnú view vrtsvu je v prostredí webu možné implementovať a dokonca je to žiadúce. Prakticky sa to robí oddelením HTML od PHP a použitím nejakého šablónového systému.
Má to minimálne dosahy na výkon, uľahčíte život sebe a každému, kto po vás bude upravovať web. Čo tým získate?
- Zbavíte sa schizofrénie. Keď píšete HTML, tak píšete HTML. Keď programujete v PHP, tak programujete v PHP
- Zmena dizajnu stránky znamená urobiť zmeny v HTML súboroch, nemusíte nijako zasahovať do PHP kódu (koľkokrát ste prepisovali PHP kód, lebo ste sa rozhodli vykresliť tabuľku trochu inak?)
- Rovnako zmena aplikačnej logiky si nevyžaduje žiadne zásahy v HTML kóde
- Pokiaľ pracujete v tíme, kde sú oddelené úlohy programátora, kódera a dizajnéra, tak sa vám všetkým bude pracovať lepšie, lebo každý robí len to, čo najlepšie vie
Sú aj argumenty proti:
- Je predsa jednoduchšie urobiť
echo "<tr><td>{$mesto}</td></tr>", ako zložito preväzovať premenné medzi PHP a HTML súbormi. - Keď generujem HTML v rámci PHP, tak máme všetko spolu a hned vidíme, čo do čoho zasahuje
Pravdupovediac, oba som zatiaľ počul len od ľudí, ktorí nikdy nepracovali v PHP so šablónami a väčšina z nich ani nevedela poriadne programovať. Málokedy sa mi ich podarilo presvedčiť. Ono je najlepšie, keď si človek sám skúsi nejaký čas pracovať s použitím nejakého šablónového systému. To by bolo na úvod všetko, teraz k tomu, o čom som chcel naozaj písať.
perunTPL
Môj prvý šablónový systém sa zrodil v čase, keď som na internete kvôli vysokým poplatkom (a nízkej rýchlosti) mohol stráviť nanajvýš pol hodinu týždenne. Netušil som, že iní ľudia také veci robia už dlho a že by mi stačilo si nejaký vybrať a začať používať. Ale toto som nevedel, tak som si napísal systém vlastný.
Počas rokov sa vyvíjal podľa potrieb, nejakú funkcionalitu som mu pridával, nejakú odoberal. Celkovo prešiel štyrmi veľkými zmenami. Jeho prvá verzi amala bez komentárov niečo cez tisíc riadkov a nepracovala s regulárnymi výrazmi. Každá ďalšia verzia počet riadkov pekne skrátila a tá najnovšia (a imho najlepšia verzia) ich má len okolo osemdesiat a verím tomu, že sa to dá ešte skrátiť. Je to veľmi jednoduchý, ale mocný systém.
Jednoduché nahradzovanie
A ako sa perunTPL používa? Najskôr potrebujete šablónu. Vytvoríte si nejaký súbor s vaším html. Povedzme, že sa
volá header.tpl a je umiestnený v adresári tpl:
<html> <head> <title>{TITULOK}</title> </head> <body> <h1>{TITULOK}</h1> <p>{UVOD}</p> </body> </html>
V tomto príklade sú uvedené jednoduché nahradzovania vzoru za hodnotu. Vzor sa v šablóne vždy umiestňuje
medzi krútené zátvorky. Pomocou metódy bind dokážete vzor previazať s hodnotou
zistenou v PHP.
include "include/peruntpl.php"; include "include/db.php"; $tpl = new perunTPL("header", "file"); $result = db_query("select title, teaser from article where id=1"); if ($obj = db_fetch_object($result)) { $tpl->bind("TITULOK", $obj->title); $tpl->bind("UVOD", $obj->teaser); } echo $tpl->get();
Výsledok:
<html> <head> <title>Hello world!</title> </head> <body> <h1>Hello world!</h1> <p>Toto je prvý záznam v tabuľke článkov</p> </body> </html>
Najskôr sme si vytvorili inštanciu triedy perunTPL. Šablónu môžeme získať
buď z reťazca, alebo načítať zo súboru. My ju načítavame zo súboru, preto je prvý parameter
názov tohto súboru (bez uvedenia adresára a prípony), druhý parameter je indikácia toho, že ide o súbor.
Tretí parameter určuje adresár, v ktorom sa má vyhľadávať šablóna (ak vynecháte, použije sa tpl/). Štvrtý parameter je prípona súboru, opäť sa môže vynechať, vtedy sa použije .tpl
Potom sme si vytiahli potrebné údaje z databázy a previazali dané premenné so vzormi v šablóne.
Vzor TITULOK sa nahradil na oboch miestach.
Získanie výsledkov nahradzovania sa deje volaním metódy get(). V našom prípade sme
výsledok hneď vypísali.
Zadaný kód sa dá aj trochu vylepšiť, metóde bind je totiž možné odovzdať naraz viacero
pravidiel nahradzovania. A to tak, že ich všetky vložíme do asociatívneho poľa a to odovzdáme ako
parameter.
... if ($obj = db_fetch_object($result)) { $tpl->bind(array( "TITULOK" => $obj->title, "UVOD" => $obj->teaser, )); } ...
Podmienky
Niektoré časti výstupu chceme zobrazovať v závislosti na podmienkach. Napríklad menu pre administrátora chceme ukázať iba administrátorom.
<ul> <li><a href='/account.php'>Môj účet</a></li> <li><a href='/new_article.php'>Napísať článok</a></li> <if-admin> <li><a href='/users.php'>Administrácia používateľov</a></li> </if-admin> <li><a href='/logout.php'>Odhlásiť</a></li> </ul>
Kusy html kódu, ktoré sa majú vykonať iba vtedy, ak je splnená určitá podmienka, sme v šablóne
obalili do tagov if-názov. Pravidlo pre metódu bind vyzerá takto:
include "include/peruntpl.php"; $tpl = new perunTPL("menu", "file"); if ($user->is_admin()) { $tpl->bind("if-admin", true); /* alternatívna syntax: $tpl->bind(array( "if-admin" => true, )); */ } echo $tpl->get();
Pokiaľ by sme ako druhý parameter pre bind dali false, alebo
hocijakú inú hodnoty, ktorú PHP vyhodnotí ako nepravdu, tak by sa celý úsek <if-admin>...</if-admin>
nahradil prázdnym reťazcom. Takisto sa nahradí prázdnym reťazcom, ak pravidlo if-admin
v PHP úplne vynecháme.
Opakovania
Poslednou základnou operáciou, ktorú môj šablónový systém ovláda, sú opakované nahradzovania. Výpis zoznamu článkov by sa dal urobiť napríklad takto:
<html> <head> <title>{TITULOK}</title> </head> <body> <h1>{TITULOK}</h1> <repeat-zoznam> <h2>{NADPIS}</h2> <p>{UVOD}</p> </repeat-zoznam> </body> </html>
Kód, ktorý chcem vypisovať opakovane a len v rámci neho meniť hodnoty určitých premenných, uzavrieme
do tagov repeat-názov. Opakovanie sa udeje toľkokrát, koľkokrát sa zavolá
metóda bind s prvým parametrom repeat-názov. Zoznam článkov by sme
teda v PHP vypísali asi takto:
include "include/peruntpl.php"; include "include/db.php"; $tpl = new perunTPL("header", "file"); $result = db_query("select title, teaser from article"); $tpl->bind(array( "TITULOK" => "Zoznam článkov", )); while ($obj = db_fetch_object($result)) { $tpl->bind("repeat-zoznam", array( "NADPIS" => $obj->title, "UVOD" => $obj->teaser, )); } echo $tpl->get();
A to je v skratke asi všetko. Pokiaľ vás knižnica perunTPL zaujala, môžete si ju stiahnuť a používať takmer neobmedzene, uverejnil som ju pod licenciou LGPLv2.1
Vidieť v zdrojáku pomiešaný PHP a HTML kód je niečo, z čoho máva každý lepší PHP programátor nočné mory. A robiť úpravy alebo hľadať chybu v danom kóde je pre neho peklo na zemi. Ešte horší prípad je, keď takto napísaný web dostane do rúk kóder alebo webdizajnér, aby upravili jeho vizuál. Prečo je miešanie PHP a HTML kódu zlé a ako sa tomu vyhnúť, o tom je nasledujúci článok.
Zatiaľ nie sú žiadne komentáre.