Régebben írtam a PHP sablonnyelvként való használatáról. Lehet szépíteni a dolgokat, de hosszú távon ennek a használata (főleg megfelelő szerkesztőprogrambeli makrók nélkül) kényelmetlen, hosszadalmas és még a makrók használatával együtt is csúnya, olvashatatlan. A Smarty egyetlen pozitívuma az, hogy egyszerűen és gyorsan lehet írni, kényelmesen lehet használni. Persze ez nem vigasz azoknak, akik nem akarnak egy több ezer kódsorból álló sablon kezelőt használni csak emiatt a kényelem miatt.

Nagyrészt így vagyok vele én is. Gyakorlatilag a szintaktikájának az alapjait leszámítva nem lenne szükségem semmire a Smarty-ból. Nem érdekel, hogy korlátozni lehet a sablon íróját, hogy a PHP eszköztár csak egy részét használhassa (minek is korlátoznám magam...). Nem érdekel, hogy könnyen és gyorsan lehet hozzá plugineket írni (ha az egész PHP használható lenne, erre nincs is túl nagy szükség). Nincs szükségem semmi ilyesmire.
Sokkal inkább vonz az, ha a nyelvet gyorsan lehet gépelni (pl. mert rövid, minimális speciális karaktert használ és logikus a szerkezete). Az se egy hátrány, ha az elkészült sablon valamilyen szinten olvasható lesz. Nem lenne rossz még, ha egy elfogadható minőségű PHP kódot generálna az én sablonomból, ami aztán elfogadható (a lehető leggyorsabb) sebességgel futna. Az első kettőt még csak-csak teljesíti, de az utolsóval eléggé hadilábon áll a Smarty. Így itt az idő valami más után nézni...

A legkézenfekvőbb dolog a PHP használata lenne erre a célra, ami az első két ponton totálisan megbukik. Kiindulási alapnak viszont jó lesz:

<h1>Valami sablon</h1>
 
<?php if (5 > 6): ?>
	<p><?php print('5 nagyobb mint 6'); ?></p>
<?php else: ?>
	<p><?php print('5 nem nagyobb, mint 6'); ?></p>
<?php endif; ?>

Mi lenne, ha első körbe a <?php és a ?> helyett a jól megszokott { és } lenne használva?

<h1>Valami sablon</h1>
 
{ if (5 > 6): }
	<p>{ print('5 nagyobb mint 6'); }</p>
{ else: }
	<p>{ print('5 nem nagyobb, mint 6'); }</p>
{ endif; }

Haladunk, esetleg még a print() helyett bevezethetnénk a PHP rövid tag <?= szerkezetéhez hasonlóan egy {= szerkezetet:

<h1>Valami sablon</h1>
 
{ if (5 > 6): }
	<p>{= '5 nagyobb mint 6' }</p>
{ else: }
	<p>{= '5 nem nagyobb, mint 6' }</p>
{ endif; }

Pár kényelmességet elősegítő lépés múlva (szóközök, kettőspontok, felesleges zárójelek, pontosvesszők eltűntetése) sikerült eljutnom a végleges formáig:

<h1>Valami sablon</h1>
 
{if 5 > 6}
	<p>{='5 nagyobb mint 6'}</p>
{else}
	<p>{='5 nem nagyobb, mint 6'}</p>
{if}

Rémisztően hasonlít a Smarty-ra (ez valamilyen szinten cél is volt :)), viszont az ebből fordított PHP kód gyakorlatilag egy az egyben megegyezik az általunk írt sablon kód szerkezetével. Most, hogy megvan az alapvető szintaxis, jöhet a sablonkezelő osztály, ami a fentebb említett több ezer sorhoz képest megvalósult úgy 170 sorból (milyen csodákra képes, ha kihagyunk minden "szemetet", amire nincs szükségünk :)), ami már tartalmaz pár extra funkciót is (mint például a lefordított sablonok újrafordítási szükségességének ellenőrzését). A bemenete egy ilyen template, amiből ezt a PHP kódot generálja, valami ilyesmi kóddal:

<?php
	include('lighty.php');
 
	$l = new Lighty();
 
	$l->assign('list', array('a', 'b', 'c', 'd'));
	$l->display('teszt.tpl');
?>

Amit érdemes ezzel kapcsolatban megemlíteni, hogy a lefordított forrás első sorának elején ott van egy kommentben a fordítás ideje, ami az újrafordítás-ellenőrző számára fontos. Valamint az egész fájl egyetlen egy PHP kódblokkot tartalmaz (ami emlékeim szerint optimálisabb, mint sok-sok kis PHP kódblokk egy sablonon belül). Emiatt vannak felesleges, csak whitespace karaktereket kiíró print() hívások, de ezek megszüntethetőek. És végül, de nem utolsó sorban, a Lighty névre keresztelt sablonrendszer első publikus verziója letölthető innen. A csomagban megtalálható egy teszt.php is, ami a fentebb felvázolt példakódot tartalmazza, valamint az általa használt template fájlok és szükséges könyvtárak is.

És hogy így a végén még a címben említett kérdést is megválaszoljam: szerintem szükség van a sablonnyelvekre, mert nagyban meg tudják könnyíteni az ember életét az által, hogy meggyorsítják a sablonírás folyamatát.

+++++

Hozzászólások Hozzászólások RSS

  1. Hasonszőrű problémával hadakozom magam is, ebből kifolyólag dupla hálás köszönet a "Könnyűkéért" :)

  2. Két kisebb bugfix történt:

    - a 87. sor környékén a fetch() visszatérése volt hibás
    - a 101. sor környékén a display() függvényben az array_merge() visszatérési értéke nem volt felhasználva

    A fenti linken már a javított verzió tölthető le.

  3. Hmm. Hát nekem elég ellentmondásos az írás. A sablonnak nem az az elsődleges szerepe, hogy gyorsabban lehessen php kódot gépelni. Persze lehet ez is cél, de a smarty-t nem lehet ide sorolni. Ezért az összehasonlítás is értelmetlen.
    Amúgy hasznos lehet a Lighty :)

    AkronOctober 31, 2007
  4. Persze, az elsődleges szerepe az lenne, hogy a megjelenítési réteget elválasszuk az alkalmazás többi részétől. De ez már megvalósul(hat) akkor is, ha a PHP-t használjuk, mint sablonnyelvet (ahogy azt nem egy keretrendszer teszi).

    Viszont azt - szerintem - ritka kényelmetlen gépelni és ezért is keletkezett az igényem a Lighty-ra... :)

  5. Történt pár módosítás a rendszerben:
    - alkönyvtárakba rendezett template fájlok kezelése,
    - üres file, lighty blokkot nem tartalmazó fájl lefordításának javítása.

    A fenti linken már a javított verzió tölthető le.

  6. Szia!

    Nagyon jó kis cuccot raktál össze! Én néhány módosítást tennék azért bele:
    - a compileCheck ne nézze a template módosítás dátumát, hanem csak akkor fordítsa újra a templatet, ha a cacheben nincs. debug szempontjából a mostani nyílván jobb megoldás, de később működő rendszernél sztem felesleges teljesítmény veszteség
    - trigger error helyett dobhatna Exceptiont
    - lehetne hozzá konstruktor vagy factory pattern, ha a templatek több különböző könyvtárakban vannak

    D.

    pixelDecember 11, 2007
  7. Lehet újra kellene értelmezni a compileCheck-et, hogy FALSE esetén sose fordítson újra, ha létezik a template, TRUE esetén meg végezze ezt az ellenőrzést. Vagy inkább egy reCompile változót bevezetni helyette, ami ha TRUE mindig újrafordít, ha FALSE akkor sose.

    Azért döntöttem a trigger_error mellett, mert ezeket a dolgokat a fejlesztés alatt úgyis ki akarja javítani az ember, nem tartok valószínűnek egy olyan esetet, hogy nem létező template esetén keletkező kivételt el akarnék kapni és valami mást csinálni abban az esetben.

    A beállítások azért lettek public-ok, hogy ne kelljen konstruktorban átadni őket, hanem példányosítás után lehessen változtatni. De persze ízlés kérdése, hogy az ember milyen megoldást választ, nálam a keretrendszer példányosítja a sablonozót, és beállítja a két könyvtárat, amit használ és egy könyvtáron belül (alkönyvtárakban) vannak a sablonok.

    Köszi az észrevételeket, a compileCheck-el mindenképpen kezdek valamit, meg van még pár ötletem, amit le kéne kódolni, úgyhogy hamarosan talán lesz új verzió... :)

  8. Hajrá, hajrá! Várom! :)

    pixelDecember 11, 2007
  9. Amúgy az errorral meg kivétellel kapcsolatban annyit, hogy nekem jobban tetszik a nem script nyelvek szemlélete (C#, Java). Arra gondolok, hogy hiba akkor keletkezik, ha fordítási időben van valami gond, exception meg akkor, ha futási időben történik valami gebasz. Mivel a fatal_error stb és társait nehéz elkapni PHP-ben, és nem túlságosan OOP szemléletű, ezért javasoltam az Exceptiont, amit viszont el lehet kapni keretrendszeren belül és le lehet nyelni, vagy ki lehet rakni egy "ízléses" exception oldalt (pl. asp.net). De ez már tényleg egyéni felfogás kérdése.

    pixelDecember 11, 2007
  10. Nos megszületett az 1.1.0-s verzió. A következő dolgok változtak:
    - compileCheck helyett reCompile lett, a fentebb írt működéssel
    - lett egy Lighty::shortcuts tömb, amivel lehet rövidíteni adatkiírások során. Például a {h='szöveg'}-ből print(htmlspecialchars('szöveg')); lesz (a tömb public, szóval lehet saját függvényekkel tovább bővíteni).
    - removeHtmlComment beállítása esetén már nem szedi ki az IE feltételes megjegyzéseket

    A kivételeken még agyalok, hogy legyen-e, és ha igen, akkor hogyan. Egyelőre maradt a trigger_error-os megoldás.

  11. az jutott eszembe, hogy szerintem jó lenne, ha többlépcsőssé lenne tehető a sablon objektum. arra gondolok, hogy az Lighty::assign() nem csak sztringet, hanem másik Lighty objektumot is tudna fogadni, így jobban átláthatóvá válnának a template fájlok.
    vagy te hogy csinálod?

    pixelJanuary 28, 2008
  12. közben látom a fetch()-t :)

    pixelJanuary 28, 2008
  13. A $l->assign('nev', $valtozo) esetén a $valtozo akár egy (Lighty) objektum is lehet, amit a templateben $nev -ként lehet elérni, bár őszintén szólva nem látom ennek értelmét/hasznát.

  14. Jó cucc, viszont a shortcutokat nem érdemes használni, maximum statikus szövegek esetében, mivel tetszőleges kódfuttatásra adhat lehetőséget. Íme egy példa:

    Ebből a kódból :

    {a="Ez egy teszt".phpinfo()}

    Ezt generálja:

    print(addslashes("Ez egy teszt".phpinfo()));

    Persze ezen is lehet segíteni egy kis input szűréssel, de inkább nem javaslom, a rövidített függvények használatát a kódban.

    scripter-man

    scripter-manOctober 28, 2009
  15. Nem igazán értem ez hol jelenthet problémát. Ha magadnak írsz ilyet a sablon kódban akkor ezt az eredményt várod. Kívülről meg most így hirtelen úgy gondolom, hogy nem érkezhet olyan input, aminek ez lenne a végeredménye.

    $lighty->assign('valami', '"Ez egy teszt".phpinfo()');

    és

    {a=$valami}

    esetén

    print(addslashes($this->templateVariables['valami']));

    lesz, ami a

    print(addslashes('"Ez egy teszt".phpinfo()'));

    kódnak felel meg. Persze a

    $lighty->assign('valami', "Ez egy teszt".phpinfo());

    esetén más a helyzet, de azzal meg ugyanott vagyunk, hogy nem érkezhet ilyen input kívülről.

  16. Smartynak alapvetően az a baja, hogy a fejlesztői nem tudnak programozni, vagy csak nem gondolták át eléggé a rendszert. A felülete kényelmes, de ami alatta van, az gáz.
    Az alap compilert 150 sorból simán ki lehet hozni, a függvényeket (úgy, mint if,foreach,include,comment...) pedig további párszáz sorból. Ehhez képest kb 5000 sor a mostani Smarty, és a sebessége is olyan...

    inf3rnoApril 5, 2010

Szólj hozzá!

regisztráció, bejelentkezés

Az oldalon nem jelenik meg.

Ezeket a tageket használhatod: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>