Kaip atskirti grūdus nuo pelų
Manau nesuklysiu pasakydamas, jog dauguma programuojančiųjų PHP žino, supranta ar bent nujaučia, kad norint sukurti lengvai atnaujinamą svetainę reikia atskirti HTML ir PHP kodą vieną nuo kito (rimti programuotojai pasakytų: atskirti programos logiką ir vaizdavimą). Šį dalyką labai lengva suprasti jau kuriant pirmasias svetaines, kai staiga prireikia pakeisti vieną neypatingai gerą svetainės dizainą kitu, dažniausiai nedaug geresniu. Prisimindamas savo patirtį šioje srityje (neypatingų dizainų kūrimo ir keitimo), noriu aptarti kelis būdus, kuriuos naudodavau anksčiau, taip pat pasidalinti naujai iškilusiomis mintimis, kurios galbūt pagelbės ir jums, sprendžiant panašias problemas.
Pirmiausia noriu pasakyti, kad dėl vietos stokos čia nenagrinėsiu grynai statinio turinio svetainių. Jei jus domina būtent tokių svetainių dizainų kaitaliojimas — rekomenduoju pabandyti išsiaiškinti Macromedia Dreamweaver šablonų teikiamas galimybes.
Pirmas bandymas: galva džiūsta, kojos pūsta
Viena pirmųjų svetainių, kurią kuriant bandžiau išspręsti šią problemą, buvo www.lvta.lt svetainė. Tai buvo mano pirmas savarankiškas PHP projektas. Jau tik “užmetęs” pirmąjį svetainės variantą iš kelių puslapių ir dar bederindamas dizainą (neypatingą), supratau, kad kaskart pataisius HTML kodą eiti ir tvarkyti jį visuose skriptuose bus labai nuobodu. Todėl nusprendžiau iškelti viršutinę HTML kodo dalį, o taip pat ir prisijungimo prie MySQL funkcijas į failą head.php, o apatinę — į foot.php. Iškart pajutau palengvėjimą, tačiau iškilo ir naujų problemų.
Su paprastesnėmis problemomis (tokiomis, kaip puslapio antraštės, kuri nurodoma puslapio skripte, vaizdavimas skripte head.php) susitvarkyti — juokų darbas. Kitos, tokios kaip sesijų valdymas, bei administravimo puslapių rodymas pareikalavo truputį daugiau dėmesio. Ramybės nedavė ir kita mintis: jei puslapis yra rodomas vienas, tai kam reikia atskirų skriptų viršui ir apačiai, kurie netgi ne visada yra viršus ir apačia, o tiesiog HTML kode eina vienas po kito.
Antras bandymas: pirma puslapio informacija, šablonas vėliau
Baigęs programuoti savo pirmąjį rimtą projektą su PHP, bei išbandęs savo programavimo sugebėjimus kuriant primityvokus, darbą palengvinančius skriptus — žodžiu tapęs mokančiu naudotis manualu PHP programuotoju, nusprendžiau pabandyti sujungti HTML šabloną iš dviejų gabalų į vieną. Tai padaryti pavyko gana sėkmingai, kuriant svetainę www.yes.lt (manau dalis sėkmės buvo ir tai, kad dizainą darė tikras dizaineris).
Būdas gana paprastas: MySQL prisijungimo funkcijas iškeliame į skriptą start.php, HTML šabloną į skriptą template.php, o puslapio skripte iš anksto nustatytiems kintamiesiems (pvz $title, $keywords, $content) priskiriame jų reikšmes. Kad būtų aiškiau, štai skriptų pavyzdžiai:
start.php:<?phptemplate.php:
$con = mysql_connect(‘localhost’, ‘root’, ”);
mysql_select_db(‘mydb’);
?>
<html><head>page.php:
<title><?php echo $title; ?></title>
</head>
<body>
<?php
echo “<h2>$title</h2>“;
echo “<p>$content</p>“;
?>
</body></html>
<?php
require(‘start.php’);
$title = ‘Mano puslapis’;
$content = ‘Tai yra mano puslapis’;
require(‘template.php’);
?>
Šis būdas labai patogus ir paprastas, kai kuriame nedidelės apimties (~20 psl.) svetaines, kurios susideda daugiausia iš statinių puslapių ir kurias numatoma greitai aplipdyti naujais puslapiais. Esu išbandęs šį metodą ne vienoje svetainėje — niekad neturėjau su juo problemų. Visgi jis irgi turi trūkumų — kurti didesnės apimties svetainėms, portalams ir web programoms (web-apps) jis yra nepatogus — per daug reikia visko sutikrinti kuriant šablonus, bei dažniausiai tokia sistema kenkia bendrai programos struktūrai.
Trečias bandymas: naudojam Phemplate
Šiek tiek pajusti, kas tai yra portalų kūrimas ir darbas komandoje, teko dirbant mauglis.com prie portalų bluway.com ir sisterstrip.com . Taip pat įgijau naujos patirties — darbo su Juozo Šalnos (pukomuko) sukurta Phemplate šablonų klase. Tuo metu jau buvau susitupėjęs PHP programeris žinojau, kad galima funkcijų biblioteką paversti klase ir apsimesti, kad tai objektinis programavimas, bei turėjau pasirašęs ir nuosavą šablonų klasę, kuri buvo pritaikyta visiškai kitokioms sistemoms, todėl daugiau jos čia neminėsiu.
Phemplate šablonų klasė man iškart patiko savo paprastumu ir aiškumu. Pavyzdžiui masyvo reikšmių išvedimas cikle:
script.php:<?phptemplate.tpl:
require(‘phemplate.class.php’);
$tpl = &new Phemplate();
$masyvas['0'] = aray(‘id’=>0, ‘name’=>‘nulis’);
$masyvas['1'] = aray(‘id’=>1, ‘name’=>‘vienas’);
$masyvas['2'] = aray(‘id’=>2, ‘name’=>‘du’);
$tpl->set_file(‘failas’, ‘template.tpl’);
$tpl->set_loop(‘mas’, $masyvas);
echo $tpl->process(”, ‘failas’, 1);
?>
<h3>Masyvas:</h3>
<loop name=”mas”>
<b>{mas.id}</b> {mas.name}<br>
</loop name=”mas”>
Vis dėl to ne viskas ėjosi sklandžiai. Mūsų mažai komandai pastoviai iškildavo problemų su klaidomis klasių metoduose. Beveik viskas ką suprogramuodavome veikė nepatikimai, kodas metoduose atrodė griozdiškai. Dėl savęs negarantuoju, bet komandos draugai buvo tikrai geri programuotojai, o visa sistema buvo išsamiai dokumentuota ir gerai suprojektuota naudojant UML…
Prisipažinsiu: iš prigimties esu labai didelis tinginys. Paprastai prieš ką nors darydamas ilgai galvoju kaip išsisukti nuo didelių nuobodaus darbo sanaudų. Tad toks kodo poreikis kruopščiam darbui mane ypač erzino ir skatino ieškoti problemos šaknų. Šaknis po ilgoko laiko atradau, labai gilias ir netgi visas dvi. 1: sistemoje buvo daug vienodų kodo gabalų atliekančių tas pačias funkcijas skirtingose vietose* — nieko bendro su šablonų tematika, tad nedetalizuosiu ir 2: nors PHP kodas ir nebuvo sumaišytas su HTML kodu, buvo sumaišyta programos logika su HTML logika. Noriu dar kartą pabrėžti — ne su vaizdavimo logika, bet būtent su HTML logika.
Štai jums realus pavyzdys**: reikia išvesti informaciją esančią masyve dviem stulpeliais tokia tvarka:
<table>
<tr><td>1</td><td>2</td></tr>
<tr><td>3</td><td>4</td></tr>
<tr><td>5</td><td>6</td></tr>
</table>
Dabar tiksliai neatsimenu kaip tą padariau su Phemplate, bet galiu jus užtikrinti, kad reikėjo bent vieno papildomo ciklo klasės metode, visiškai nesusijusio su programos logika, o susijusio su HTML logika: tai kad kiekvieni du <td>…</td> turėjo būti apsupti vieno <tr>…</tr>. Bendrai paėmus tokių papildomų ciklų, sąlygų tikrinimų ir kitų dalykų, susijusių su HTML vaizdavimu prisikaupdavo daug ir jie užgoždavo programos logikos kodą: operacijas su duomenų baze, duomenų tikrinimus ir kt..
Taigi, net ir gana plačiai pripažintos šablonų klasės gali pakišti koją ir netgi vykdyti pogrindinę kenkėjišką veiklą: savo metodais maskuoti tai, kad iš tikro rašai tą patį HTML kodą tarp PHP kodo eilučių… Šiuo nenoriu pasakyti, kad Phemplate yra bloga klasė. Manau, kad ši klasė idealiai tinka paprastiems šablonams ir paprastoms svetainėms, bet ne sudėtingesniems darbams.
Ketvirtas bandymas: o gal į viską pažvelgti paprasčiau?
Stengdamasis pagerinti kodą pradėjau naikinti pirmąją problemos šaknį ir dalinai spręsti antrąją: visą PHP kodą, susijusį su Phemplate iškėliau į atskirus klasių metodus (kuriuos, kad atskirčiau nuo programos logikos metodų pavadinau widget’ais), bei pabandžiau sumažinti šių metodų skaičių naudodamas tokius triukus, kaip vieno šablono (ir vieno metodo) naudojimą tiek duomenų įvedimo, tiek redagavimo formos vaizdavimui ar pan.. Situacija pagerėjo iškart — a) kodas rašėsi greičiau (buvo galima daugiau tinginiauti), b) kodas buvo aiškesnis, c) sumažėjo klaidų kiekis kode.
To man dar buvo negana — dirbdamas jau prie kito, asmeninio, užsakymo nutariau žengti dar vieną žingsnį ir iškelti widget’us iš klasių kodo į atskiras funkcijų bibliotekas, atsisakyti šablonų klasės naudojimo, taip funkcijos viduje sumaišant PHP ir HTML, bei susikurti universalių widget’ų, tokių kaip puslapiavimo išvedimo ar pan.. Čia tai jau prasidėjo! Manau jausmas toks, kaip Delphiu programuojant grafinę programą Windows’ams — duomenis pasiimi iš duombazės ir iškvietęs kokį vartotojo aplinkos (user interface) elementą atiduodi jam juos [duomenis] ir iškart gėriesi gražiai pavaizduota informacija.
Netyčia prisiminęs išvesties buferio (output buffering) funkcijas padariau kolkas paskutinį patobulinimą — pasirašiau nuosavą šablonų klasę (pavadinau ją ctlTpl***). Ši klasė man leidžia atsisakyti ir šablonų kaip widget funkcijų, valdydama šablonams skirtus duomenis ir leisdama kurti šablonus, naudojant pačią patogiausią šablonų sintaksę — PHP kodą****. Štai pavyzdys:
example.php:
<?phpexample.tpl:
require(‘ctl.tpl.class.php’);
$tpl = &new ctlTpl();
$arr[] = array(‘title’=>‘News1′, ‘content’=>‘msg1′);
$arr[] = array(‘title’=>‘News2′, ‘content’=>‘msg2′);
$arr[] = array(‘title’=>‘News3′, ‘content’=>‘msg3′);
$tpl->setVar(‘news’, $arr);
$tpl->setVar(‘title’, ‘News page’);
echo $tpl->process(‘example.tpl’);
?>
<html><head><title><? echo $title; ?></title></head>
<body>
<h2><? echo $title;?></h2>
<?
foreach ($news as $n)
{
echo “<b>$n[title]:</b> $n[content]<br>“;
}
?>
</body></html>
Kaip, tikiuosi, matyti iš pavyzdžio, šablone galima naudoti visas PHP funkcijas, kurių tik galite užsigeisti, taip pat šablono nagrinėjimas (parsing) yra labai efektyvus ir greitas, nes tam naudojamas vidinis PHP parseris.
Naująją klasę išsibandžiau kurdamas svetainę www.oasis.kz — esu labai ja patenkintas ir nebejaučiu poreikio ieškoti dar patogesnės sistemos. Be patogumo radau ir dar vieną privalumą: naudojant PHP šablono valdymui, galima lengvai kurti “gudrius” šablonus, kurie patys prisitaiko prie vaizduojamos informacijos kiekio ar ypatybių (pavyzdžiui nuotraukos produkto puslapyje išdėstomos skirtingai, priklausomai nuo to ar produktas turi aprašymą, ar ne).
Be abejo ši šablonų sistema irgi turi savo trūkumų. Galiu suminėti bent porą: šablonus rašantis žmogus turi turėti bent PHP kodavimo pagrindus (jei leidžiate savo dizaineriui kurti HTML arba jūsų HTML’eris išskirtinai nemokytinas, ši sistema deja jums netiks), taip pat šablonus rašantis asmuo galės prieiti prie PHP kodo (gali būti nepriimtina kai kuriais atvejais, kai šablonų valdymas atiduodamas paprastiems sistemos vartotojams).
Kodėl nerekomenduoju Smarty ar XSLT?
Tikrai ne dėl to, kad nelaikyčiau šių PHP klasės ir šablonų kalbos nesusijusių su aptariama tema ar nevertų dėmesio. Nerašiau apie jas todėl, jog manau, kad jos yra dideli gargarai reikalaujantys daug dėmesio ir darbo, o už tai duodantys palyginti mažai.
Smarty: gana sudėtinga sintaksė, kurią reikia išmokti ir kuri tik dubliuoja PHP kodą. Be to Smarty reikia instaliuoti į svetainę — žaisti su chmod ir panašiais dalykėliais, o tai papildomas vargas.
XSLT: kartą esu pasirašęs sintaksės griozdiškumu panašią šablonų kalbą. Nuo to laiko negaliu be pasibjaurėjimo žiūrėti į tagais aprašomas programavimo kalbas — žvilgtelėkite ir jūs į kokį XSLT failo pavyzdį ir pasistenkite ten susigaudyti. Manau, kad ne viskas, kas prasideda raide ‘X’ ar yra susiję su XML ir W3C yra būtinai naudotina ir laikytina būsimu standartu. Taip pat manau, kad ne viskas, kas tinka didžiulei IT įmonei vakaruose, tiks jums ir man Lietuvoje.
Išvados
- Ne visi geri dalykai tinka visais gyvenimo atvejais.
- Prieš naudojantis šablonų klasėmis reikia rimtai pagalvoti kam jas naudojame ir ką tuo pasieksime.
- Mada ir įvaizdis dar ne viskas — troškulys yra viskas (arba kodo patogumas ir efektyvumas).
- Kartais tinginiu būti visai malonu ir naudinga (o kartais ir ne).
* pvz. vien vartotojo registracijos formos šablonų (vienodų paskirtimi ir informacijos pobūdžiu) keliems portalams buvo naudojama 52!
** užeikite į http://www.bluway.com/personals/, kad pamatytumėte rezultatą.
*** Klasę galite parsisiųsti iš http://www.phpclasses.org/browse.html/package/937.html.
**** suprasti, kad PHP yra pati patogiausia šablonų kalba padėjo buvęs mano bendradarbis Almantas, už ką jam labai dėkoju
Beje, jau parašęs straipsnelį netyčia užtikau panašų straipsnį:
<a href=”http://www.phppatterns.com/index.php/article/articleview/4/1/1/”>www.phppatterns.com/index.php/article/articleview/4/1/1/</a>
Autorius atrodo daugiau už mane patyręs developeris, bet mintys bendrai paėmus panašios. Tikiuosi tai reiškia, kad nevisiškai klystu :]
geras straipsnis, aciu.
Bishki nesupratau idejos.. Shablonai ir yra tam kad atskirtum koda nuo HTML, o dabar dar i shablonus savo templeitu klasej dedi PHP koda. Tai kam ish vis tu shablonu jei grizhtam prie to pachio?
Citata:
XSLT: kartą esu pasirašęs sintaksės griozdiškumu panašią šablonų kalbą. Nuo to laiko negaliu be pasibjaurėjimo žiūrėti į tagais aprašomas programavimo kalbas — žvilgtelėkite ir jūs į kokį XSLT failo pavyzdį ir pasistenkite ten susigaudyti.
O tu liepk dizaineriui zhiureti i PHP koda templeituose ir jis arba
1) nieko nesusigaudys;
2) labai gerai susigaudys ir susimastys kam tu ish vis reikalingas, jei PHP koda dizaineris turi pats rashyt.
Dizainas turi likt prie HTML. XSLT yra transformavimo kalba, skirta programuotojams. Dizaineriai nebent nagus turi kishti prie XSL. Nu mano tokie pamastymai gal kvaili.
TIkrai geras straipsniukas
. Phenx taip ir toliau..!
Saunus straipsnis, man kaiptik aktualu kaip padaryti paprasciau didele svetaine, tai kaip sakant nereikes man paciam isnaujo isbandyt visus kelius.
Geri pastebėjimai, tiesą sakant aš tai ir parašiau paskutiniam paragrafe prieš "Kodėl nerekomenduoju Smarty ar XSLT?" – mano sistema netiks, jei HTML atiduodate kurti dizaineriui.
Nelaikau tai dideliu trūkumu, nes retai tenka susidurti su tuo, kad HTML kurtų dizaineris (pats tokios praktikos labai vengiu). Iš kitos pusės, jei gauni gatavą HTML su dizainu iš jo padaryti templeitą nėra problema.
Be to man svarbiau išlaikyti švarų kodą pačioje programoje, o templeitai vistiek gi dažnokai keičiami ;]
Gal ir nieko straipsnialis pradedantiesiems
pats perziurejau smarty ir nusprendziau jos nenaudot.
gerew phemplate – ir paprasta ir patogu.
Xawiers: mazai smarty ziurejai reiskias
perejus normaliai nuo phemplate ant smarty, templeitus gamint pasidare tikrai PAPRASCIAU ir GREICIAU [ypac sudetingesnius]. Jei templeitas ten tik is paprasto ciklo, tai pagal ideja paprasciau ir su phemplate, taciau su phemplate didziausia knisalyne yra kai reikia daryt salygas ("if’us") ir kokiam nors dvigubam cikle, tai ten tarp bloku ir loop’u tiesiog ‘kaifuot’ pradedi.
Ne, visgi PHP naudojimas templeitams – nesamone.
PS: cia man vaidenasi ar bugina postai? parasau tik kabute: \’ ir slasha: \\. postinu, ziuriu kas darosi..
ups!:) \"smagu\"
wikiz: o tu žinai kam reikalingi bent templeitai, kad šauki : nesąmonė?;^)
Fainas straipsnis
Emili, del XSLT tai tu dar karta pagalvok
Nėra jokios natūralesnės kalbos templeitams, nei XSLT (ypač kai dirbama su XML duomenimis). Joje gali aprašyti visą HTML’ą, be to, naudoti sąlygos sakinius, ciklus (ne visai standartinius, bet labai tinkamus), ir visą kitą, dėl ko PHP programeris tikrai neturėtų sukt galvos. Tai HTML koderio/dizainerio sfera.
Dabar pats perkelinėju saitą nuo Phemplate ant XSLT templeitų. Pvz. Phemplate natūraliai neturi tokio dalyko, kaip <xsl:if>. <loop> (dažniausiai) atitinka <xsl:for-each>, ir t. t. Žodžiu XSLT is way2go ;]
Mano nuomone Smarty siek tiek per sudetingas paprastiems saitams, nebent svetaine a*uje*itelna. It depends on your needs, kaip sakoma
Na del XSLT tai manau kad esi siek tiek neteisus Emili. Pats programuoju Java, ir kol nemokejau XSLT parsinau XML’a su jDom’u, bet kai tik pradejau mokintis XSLT pastebejau tikrai nemazas galimybes.
1. XSLT tikrai nesunku ismokti, ir beje kodas tikrai nera painus (priklauso nuo to kaip jis parasytas).
2. kaip jau minejo kazkas komentaruose XSLTturi primityvias programavimo konstrukcijas: cikla, salygos sakyni, kintamuosius…
3. XSLT yra vienas is aiskiausiu budu atskirti programavimo logika nuo prezentacijos.
Pats neseniai ant smarty perejau. geras daiktas, lengva ir aisku viskas, ir patogu, ir, kas labai svarbu, extandable. xslt neesu bandes ir kol kas nesiruosiu
.
o phemplate ar fastemplate labiau tinka nedideliems templeitams.
u
Emili, fantastitskas straipsnis. Gaila, kad Tavo bloga atradau tik siandien. Buciau sutaupes 24 val. Snekant apie tavo padarytus \"atradimus\", man akis atvere: Savant phpsavant.com .
Mano menku supratimu: templates tikslas ne atskirti PHP nuo HTML, o programos logika nuo vaizdavimo.
GERAS