phemplate @ php.lt Konf2004

phemplate šablonų varikliuko panaudojimas

Juozas Šalna

2004

apie šnekėtoją

apie ką šnekėsiu

jei jau esate susipažinę su phemplate, tai matyt teks palaukti panaudojimų triukų dalies, nes visa kita yra common knowledge.

problema (1)

mano paties kodas iš 1999 metų:

<?
while ($row=mysql_fetch_array($result)) {
echo "<tr bgcolor=\"#B59C51\">\n";
echo "<td><TT>".$row["id"]."</TT></td>\n";
echo "<td><input type=checkbox name=\"ide[]\" value=".$row["id"]."></td>\n";
echo "<td><TT>".$row["author"]."</a></TT></td>\n";
echo "<td><TT>&nbsp;".stripslashes($row["message"])."</TT></td>\n";
echo "<td><TT><a href=\"http://saitas/show.php3?iid=".$row["hid"]."\">pix</a></TT></td>\n";
echo "</tr>\n\n";
}
mysql_free_result($result);
?>

phpMyAdmin:

$vertical_display['textbtn'] = '<td' . $rowspan . ' align="center" valign="middle">' . "\n"
. '        <a href="' . $text_url . '">' . "\n"
. '            <img src="./images/' . (($dontlimitchars) ? 'partialtext' : 'fulltext')
. '.png" border="0" width="50" height="20" alt="'
. (($dontlimitchars) ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'])
. '" title="' . (($dontlimitchars) ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'])
. '" /></a>' . "\n" . '    </td>' . "\n";      
geriau reiktų dėti syntax highlighted

problema (2)

web architektūra

įvadas į šablonus (1)

įvadas į šablonus (2)

šablonas

Sveikas, ###vardas###!
Pasididink ###pavadinimas### ###kiekis### coliais!

duomenys

vardas=Petras
pavadinimas=Joniukas
kiekis=3

rezultatas

Sveikas, Petras!
Pasididink Joniukas 3 coliais!

phemplate

phemplate

phemplate istorijėlė

sąvokos

trumpas pavyzdukas

šablonas: example01.txt

Sveikas, {vardas}!
Tu laimėjai {kiekis} pinigų!
Atsiųsk savo kortelės numerį, mes tau pervesim!

programa: example01.php

<?
include('phemplate.class.php');
$tpl = new phemplate();
$tpl->set_file('failas', 'example01.txt');
$tpl->set_var('vardas', 'Petras');
$tpl->set_var('kiekis', 'milijonus');
echo $tpl->process('', 'failas');
?>

rezultatas

Sveikas, Petras!
Tu laimėjai milijonus pinigų!
Atsiųsk savo kortelės numerį, mes tau pervesim!

trumpas pavyzdukas - šablono žymės

Sveikas, {vardas}!
Tu laimėjai {kiekis} pinigų!
Atsiųsk savo kortelės numerį, mes tau pervesim!

trumpas pavyzdukas - programa (1)

include('phemplate.class.php');
$tpl = new phemplate();

kuriame varikliuko objektą. būtinas žingsnis.


$tpl->set_file('failas', 'example01.txt');

kintamajam failas priskiriame failo example01.txt turinį.

trumpas pavyzdukas - programa (2)

$tpl->set_var('vardas', 'Petras');
$tpl->set_var('kiekis', 'milijonus');

priskiriame reikšmes šablono kintamiesiems.


echo $tpl->process('', 'failas');

gaminam rezultatą ir jį atspausdinam.

kintamieji, failai, blokai

masyvo padėjimas į šabloną (1)

turim tokius duomenis:

$seima["tetis"] = "Petras";
$seima["mama"] = "Pamela";
$seima["sunus"] = "Jonukas";
$seima["dukra"] = "Brytnė";

kaip juos sudėti į varikliuką? galima taip:

$tpl->set_var('tetis', $seima['tetis']);
$tpl->set_var('mama', $seima['mama']);
$tpl->set_var('sunus', $seima['sunus']);
$tpl->set_var('dukra', $seima['dukra']);

šablone tai pasiekiama taip:

aš - {sunus}, o ant manęs rėkia {tetis}, {mama} ir {dukra}

masyvo padėjimas į šabloną (2)

bet phemplate supranta, kas yra masyvas

$tpl->set_var('seima', $seima);

masyvo elementai pasiekiami pridėjus prie kintamojo vardo tašką:

{seima.sunus} ir {seima.tetis} geria,
o {seima.mama} ir {seima.dukra} rėkia

masyvo padėjimas į šabloną (3)

galima sudėti kiek norima gilius masyvus:

$seima["sunus"]["anukas"] = "Girtautas";
$seima["dukra"]["anuke"]["proanuke"] = "Blaivimantė";	
{seima.sunus.anukas} ir {seima.dukra.anuke.proanuke} dar negeria

reikšmių keitimas

kintamuosius į varikliuką reikia sudėti, kai jie turi reikiamas reikšmes

$vieta = "paskutinis";
$tpl->set_var('kelintas', $vieta);
$vieta = "pirmas";
echo $tpl->process('', 'failas');
aš atbėgau {kelintas}!

rezultatas:

aš atbėgau paskutinis!

pirmi du process() parametrai (1)

<ką padėjau> = $tpl->process(<kur padėti>, <iš ko paimti>)

$tpl->set_var('kazka', 'pieną');
$tpl->set_var('sukis', 'gerkit {kazka} kasdieną!');
$tpl->process('sukio_vieta', 'sukis');
echo $tpl->process('', 'failas');
šios dienos šūkis:
{sukio_vieta}

rezultatas:

šios dienos šūkis:
gerkit pieną kasdieną!

pirmi du process() parametrai (2)

process(<target>, <source>)

jūs dar su manimi?

kelių failų sujungimas (1)

puslapio šablonas: example02_page.txt

galvelė
{menu}
{content}
kojelė

meniu šablonas: example02_menu.txt

alus / vynas / degtinė / pienas

turinio šablonas: example02_alus.txt

tu geri, aš geriu, jisji geria - mes girti

kelių failų sujungimas (2)

programa: example02.php

include('phemplate.class.php');
$tpl = new phemplate();
$tpl->set_file('page', 'example02_page.txt');
$tpl->set_file('menu', 'example02_menu.txt');
$tpl->set_file('content', 'example02_alus.txt');
echo $tpl->process('', 'page');

rezultatas:

galvelė
alus / vynas / degtinė / pienas
tu geri, aš geriu, jisji geria - mes girti
kojelė

kelių failų sujungimas (3)

kokį šabloną dėti į turinį, galima nuspręsti iš parametrų.

$page = ereg_replace("[^0-9a-zA-Z_.]", "", $_POST['page']);
$tpl->set_file('content', "puslapiai/$page.html");

blokai (1)

blokai (2)

{kintamasis} ne tekstas
<block name="kintamasis">čia</block name="kintamasis">

užkraunant tokį šabloną su set_file() , būtina trečiu parametru nurodyti, kad šablone gali būti blokų:

$tpl->set_file('failas', 'blokai.html', TPL_BLOCK);

rezultatas:

čia ne tekstas

kelių failų sujungimas (4)

naudojam jau aprašytą puslapių rodymo sistemą pagal parametrus. tik dabar žinom apie blokus ir norim keisti tekstus išorėje.

puslapio šablonas:

<html><head>
<title>{title}</title>
</head><body>
<h1>{title}</h1>
{content}
</body></html>

programos fragmentas:

$page = ereg_replace("[^0-9a-zA-Z_.]", "", $_POST['page']);
$tpl->set_file('content', "puslapiai/$page.html", TPL_BLOCK);

kelių failų sujungimas (5)

turinio šablonas:

<block name="title">PAVADINIMAS</block name="title">
truputėlis turinio

rezultatas:

<html><head>
<title>PAVADINIMAS</title>
</head><body>
<h1>PAVADINIMAS</h1>
truputėlis turinio
</body></html>

komponavimas

blokus galima rodyti pasirinktinai:

mano kaimyno, valeros, išsigelbėjimas šiandien - {gerimas}
<block name="alus">tornado</block name="alus">
<block name="vynas">rašalėlis</block name="vynas">
<block name="odekalonas">trainoj</block name="odekalonas">

bloką pasirenkam priklausomai nuo savaitės dienos:

$tpl->set_file('failas', 'example03.txt', TPL_BLOCK);
$pasirinkimas = date("w") % 3;
switch ($pasirinkimas) {
  case 0: $tpl->process('gerimas', 'alus'); break;
  case 1: $tpl->process('gerimas', 'vynas'); break;
  case 2: $tpl->process('gerimas', 'odekalonas'); break;
}
echo $tpl->process('', 'failas');

ciklai

ciklo duomenų struktūra

ciklui tinkanti struktūra:

$loop = array(
0 => array(
  'id' => 1,
  'name' => 'alus',
  'laipsniai' => '5'
),
1 => array(
  'id' => 4,
  'name' => 'vynas',
  'laipsniai' => '16'
),
2 => array(
  'id' => 12,
  'name' => 'degtinė',
  'laipsniai' => '40'
),
3 => array(
  'id' => 13,
  'name' => 'pienas',
  'laipsniai' => 'pavojingas'
)

ciklo šablonas (1)

šablonas:

nuožmūs gėrimai:
<loop name="gerimai">
* {gerimai.name}, stiprumas - {gerimai.laipsniai}%      
</loop name="gerimai">

programa:

$tpl->set_loop('gerimai', $loop);
echo $tpl->process('', 'failas', TPL_LOOP);

ciklo šablonas (2)

rezultatas:

nuožmūs gėrimai:
* alus, stiprumas - 5%
* vynas, stiprumas - 16%
* degtinė, stiprumas - 40%
* pienas, stiprumas - pavojingas%

ciklo struktūros kūrimas iš mysql duomenų

kaip iš mysql resulto pasigaminti struktūrą tinkančią ciklui

function get_result() {
$res = array(); // kad neverktų 'Undefined variable'
while ($row = mysql_fetch_array()) {
$res[] = $row;
}
return $res;
}

tokios funkcijos panaudojimas:

mysql_query("SELECT * FROM naujienos");
$result = get_result();
$tpl->set_loop('news', $result);

pavyzdys su naujienomis

tarkim lentelėje naujienos yra šie stulpeliai: id, data, antraste, tekstas

konstruojame šabloną:

<loop name="news">
  {news.data} - {news.antraste}
  {news.tekstas}
  <noloop name="news">
    šiuo metu jokių naujienų nėra
  </noloop name="news">
</loop name="news">

programa:

mysql_query("SELECT * FROM naujienos");
$result = get_result();
$tpl->set_loop('news', $result);
echo $tpl->process('', 'failas', TPL_NOLOOP);

įdėtiniai ciklai (1)

tarkim yra dar viena lentelė kategorijos, pagal kurias suskirstytos naujienos. tokiu atveju reikia naudoti įdėtinius ciklus (nested loops).

konstruojame šabloną

{naujienos}
      
<block name="category">
*** {info.name} ***
<loop name="news">
  {news.data} - {news.antraste}
  {news.tekstas}
  <noloop name="news">
    šiuo metu jokių naujienų nėra
  </noloop name="news">
</loop name="news">

</block name="category">
      

įdėtiniai ciklai (2)

programa:

$tpl->set_file('failas', 'news.html', TPL_BLOCK);
mysql_query("SELECT * FROM kategorijos");
$cat = get_result();

for ($i = 0; isset($cat[$i]); $i++) {
  $tpl->set_var('info', $cat[$i]);
  mysql_query("SELECT * FROM naujienos WHERE kategorija=". $cat[$i]['id']);
  $news = get_result();
  $tpl->set_loop('news', $news);
  $tpl->process('naujienos', 'category', TPL_NOLOOP | TPL_APPEND);
}
echo $tpl->process('', 'failas');

įdėtiniai ciklai (3)

galimas rezultatas:

*** gėrimai ***
2004-02-16 - neramumai lietuvos pieno ūkyje.
petronėlės melžėjauskienės karvė įsilipo į beržą skinti obuolių.
savininkė visiškai nesijaudina ir 
sako turinti silkių ir automobilį.

2004-01-23 - nauja pieno rūšis jau su laipsniais!
ūkininkė petronėlė melžėjauskienė išvedė naują karvių veislę...

*** maistas ***
šiuo metu jokių naujienų nėra

*** pramogos ***
2004-01-26 - konkursas: kas išgers daugiau pieno!
nugalėtojui bus padovanota karvė.
konkurso metu tualetai bus užrakinti.
      

jūs dar su manimi?

sąlyginiai blokai (1)

sąlyginiai blokai (1)

kas nedirba, tas 
<opt name="gerimas">geria {gerimas}</opt name="gerimas">
<opt name="valgis">valgo {valgis}</opt name="valgis">
$tpl->set_var('gerimas', 'pieną');
echo $tpl->process('', 'failas', TPL_OPTIONAL);
kas nedirba, tas geria pieną

žymių šalinimas

ką daryti su kintamaisiais, kurių reikšmės nebuvo įdėtos į varikliuką?

tam yra funkcija set_unknowns(), kuri priima tokius parametrus:

daugiakalbystės pavyzdys

lang.lt.php

$lang['title'] = 'Pavadinimas';
$lang['menu'] = 'Meniu';
$lang['choose_one'] = 'Pasirinkite vieną';
include("lang.$lang_name.php");
$tpl->set_var('lang', $lang);

šablonas

<html markup> {lang.title} <html markup>
{lang.choose_one}

greičio mėgėjams

kaip kuo greičiau parodyti daugiau puslapių?


alternatyvos

galbūt jums reikia, kad

klausimai

?? ?? ??

pabaiga

PABAIGA

šias skaidres galima rasti adresu:
http://pukomuko.esu.lt/phemplate/slides/