Najnovšie na Twitteri
    sledujte môj Twitter
    Moje projekty

    perunTPL - šablónový systém pre PHP

    Publikované: 16.05.2009 17:39 | Zobrazené: 1019x

    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?

    1. Zbavíte sa schizofrénie. Keď píšete HTML, tak píšete HTML. Keď programujete v PHP, tak programujete v PHP
    2. 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?)
    3. Rovnako zmena aplikačnej logiky si nevyžaduje žiadne zásahy v HTML kóde
    4. 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:

    1. Je predsa jednoduchšie urobiť echo "<tr><td>{$mesto}</td></tr>", ako zložito preväzovať premenné medzi PHP a HTML súbormi.
    2. 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.

    <?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.

    <?php
    ...
     
    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:

    <?php
     
    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:

    <?php
     
    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

    Pošli na: Facebook   vybrali.sme.sk
    Komentáre:

    Zatiaľ nie sú žiadne komentáre.

    Pridať komentár