Connect with us

Cześć, czego szukasz?

Internet Maker

System szablonów PHPTAL

PHPTAL jest implementacją pythonowskiego systemu Zope Page Template w języku PHP. Jego cechą charakterystyczną odróżniającą go od Smarty jest to, że zmienne występują wyłącznie w atrybutach znaczników. Poznanie biblioteki PHPTAL pozwala spojrzeć na podział przetwarzanie/ prezentacja z nieco węższej perspektywy.

Instalacja i pierwszy skrypt

Biblioteka PHPTAL jest rozpowszechniana w postaci
spakowanego archiwum {stala}latest.tar.gz{/stala}. Po rozpakowaniu
archiwum otrzymamy plik {stala}PHPTAL.php{/stala}
oraz folder PHPTAL/. Instalacja pakietu PHPTAL sprowadza
się do umieszczenia pliku {stala}PHPTAL.php{/stala} oraz
folderu {stala}PHPTAL/{/stala} w miejscu zawartym w ścieżkach
dostępu, np.:

C:\php\PEAR\PHPTAL.php
C:\php\PEAR\PHPTAL\

Skrypt stosujący szablony PHPTAL składa się
z dwóch plików: {stala}index.php{/stala} oraz {stala}sz.html{/stala}. Pliki te
należy umieścić w tym samym folderze. Plik index.
php zawiera instrukcję dołączającą bibliotekę {stala}PHPTAL{/stala},
utworzenie obiektu {stala}$template{/stala} oraz instrukcje
przetwarzające szablon:

execute();
}
catch (Exception $e){
  echo $e;
}
?>

Parametrem konstruktora {stala}PHPTAL(){/stala} jest nazwa
pliku z szablonem. Plik {stala}sz.html{/stala} zawiera kod HTML
strony powitalnej:


  

Witaj

Zmienne

Przekazywanie zmiennych

W bibliotece PHPTAL zmienne szablonu są przekazywane
jako właściwości obiektu {stala}$template{/stala}:

$template->tytul = \'Lorem ipsum\';
$template->tekst = \'Dolor sit amet\';

lub poprzez wywołanie metody {stala}set(){/stala}:

$template->set(\'tytul\', \'Lorem ipsum\');
$template->set(\'tekst\', \'Dolor sit amet\');

W szablonie {stala}sz.html{/stala} dostęp do zmiennych uzyskujemy
stosując nazwę właściwości:

tytuł zastępczy

treść zastępcza

Jeśli do szablonu przekażemy zmienną o nazwie
abc i wartości abecadło:

$template->abc = \'abecadło\';

to w szablonie operujemy nazwą abc, podając ją
jako wartość atrybutu {stala}tal:content{/stala}:

xyz

Powyższy znacznik spowoduje zastąpienie tekstu
xyz napisem abecadło (tj. treść elementu p zostanie
zastąpiona wartością zmiennej o nazwie abc).

Wygenerowany zostanie następujący kod HTML:

abecadło

Zwróćmy uwagę, że tekst xyz pomiędzy znacznikami {html}

oraz 

{/html} może być dowolny, gdyż ulega
zamianie.

Atrybuty

Wartości atrybutów

Wartości atrybutów znaczników HTML ustalamy wykorzystując
{stala}tal:attributes{/stala}. Ze skryptu index.php do
szablonu przekazujemy wartość atrybutu:

$template->url = \'lorem.html\';

Natomiast w szablonie wywołujemy {stala}tal:attributes{/stala},
podając nazwę atrybutu (href) oraz nazwę
zmiennej (url), która ma być użyta jako wartość:

...

Kilka atrybutów

Pojedynczy znacznik HTML może zawierać kilka
atrybutów. W takiej sytuacji atrybut {stala}tal:attributes{/stala}
zawiera kilka wpisów oddzielonych średnikiem. Do
szablonu przekazujemy zmienne klasa oraz identyfikator:

$template->klasa = \'naglowek\';
$template->identyfikator = \'glowny\';

W szablonie w atrybucie {stala}tal:attributes{/stala} wymieniamy
zarówno class, jak i id, podając nazwy zmiennych,
które mają być użyte jako wartości:

lorem

Powyższy szablon wygeneruje kod:

lorem

Składanie wartości atrybutu z kilku zmiennych

Niekiedy atrybut HTML może powstawać z kilku
zmiennych przekazanych do szablonu. W takiej sytuacji
wykorzystujemy modyfikator string.

Do szablonu przekazujemy etykietę hiperłącza,
folder oraz fragment nazwy pliku:

$etykieta = \'Dolor sit amet\';
$folder = \'fld/dir/\';
$url = \'lorem.html\';
$template->etykieta = $etykieta;
$template->folder = $folder;
$template->url = $url;

Na bazie tych trzech zmiennych należy wygenerować
odnośnik:

Dolor sit amet

W PHP zadanie to realizują instrukcje:

echo \'\';
echo $etykieta;
echo \'\';

W szablonie PHPTAL należy wykorzystać atrybuty
{stala}tal:content{/stala} oraz {stala}tal:attributes{/stala} w następujący
sposób:

a

Podsumowanie

Główną przyczyną umieszczenia instrukcji przetwarzania
szablonu w atrybutach HTML była – jak podaje
dokumentacja – chęć stosowania edytorów
wizualnych. Argument ten wydaje się ważny wyłącznie
dla osób pracujących w programach WYSIWYG.

Jako zwolennik ręcznego pisania kodu (PHP/HTML/CSS) nie uznałbym tego za ważny plus. Jednak
z takiego podejścia wynikają inne, moim zdaniem
ważniejsze, korzyści:

  • silniejsze wymuszenie programowania obiektowego,
  • bardziej rygorystyczna niż to ma miejsce na przykład

w przypadku Smarty separacja przetwarzania
od prezentacji.

Dokumentacja PHPTAL jawnie zaleca stosowanie
obiektów oraz korzystanie z metod, które decydują
o przetwarzaniu szablonu. W miejsce wyrażeń
osadzanych w szablonie:

...

zalecane jest zdefiniowanie metody {stala}hasMoreThan-FiveItems(){/stala}:

 ...

W ten sposób zawartość szablonu sprowadzi
się do odczytywania właściwości i wywoływania
metod obiektów przekazanych do szablonu. Podejście
takie zastosowane w odniesieniu do wszystkich
aspektów szablonu spowoduje, że atrybuty
(m.in. href hiperłączy) będą także przekazywane
jako właściwości lub zwracane przez metodę.

W miejsce:

a

pojawi się:

a

Mimo że pozostanę użytkownikiem szablonów
Smarty (głównie z powodu trudności w generowaniu
przy użyciu PHPTAL plików tekstowych oraz LaTeX-a), to uważam, że lekcja wypływająca z poznania
systemu PHPTAL jest bardzo ważna. Uściśla bowiem
zakres obejmowany pojęciami przetwarzanie
oraz prezentacja. Im precyzyjniej określimy wszystkie
cechy prezentacyjne aplikacji, tym łatwiej będzie
w przyszłości wprowadzać zmiany w kodzie.

Rozbicie szablonu na kilka plików

Makrodefinicje

W celu rozbicia dużego szablonu na kilka plików
w PHPTAL stosujemy makrodefinicje. W osobnym
pliku o nazwie {stala}makro-menu.html{/stala} umieszczamy definicję
makra o nazwie {stala}main_menu{/stala}:

W szablonie głównym makro wywołujemy korzystając
z atrybutu {stala}metal:use-macro{/stala}. Wartość atrybutu
zawiera nazwę pliku oraz nazwę makrodefinicji:

Znacznik {html}{/html}, który zawiera wywołanie
makra, jest automatycznie usuwany. Nie pojawia
się on w generowanym kodzie HTML. Ponieważ tak
zapisany znacznik span jest niepoprawny, lepiej do
wywoływania makr stosować br:


Przekazywanie zmiennych do makr

Wszystkie zmienne przekazane do szablonu, np.
tytul oraz opcje:

$template->tytul = \'lorem ipsum\';
$template->opcje = array(\'dolor\', \'sit\');

są automatycznie dostępne wewnątrz makr. Makrodefinicja
menu zawarta w pliku {stala}makro-menu.html{/stala}
wykorzystuje obie zmienne tytul oraz opcje:

...

  • ...

Obiekty

Dostęp do pól obiektów

Do przekazywania złożonych danych dokumentacja
PHPTAL zaleca stosowanie klas i obiektów. Po
zdefiniowaniu klasy Osoba:

class Osoba
{
  public $imie;
  public $nazwisko;
  function_construct($AImie, $ANazwisko)
  {
    $this->imie = $AImie;
    $this->nazwisko = $ANazwisko;
  }
}

do szablonu przekazujemy obiekt o nazwie student:
{stala}$template->student = new Osoba(\’Jan\’, \’Kowalski\’){/stala}
W szablonie publiczne pola obiektu są dostępne
jako: student/imie oraz student/nazwisko:


  ...
  ...

Obiekty Propel

W przypadku obiektów generowanych przez oprogramowanie
Propel dostęp do pól jest realizowany
metodami {stala}get(){/stala}. PHPTAL pozwala na wywoływanie
dowolnych metod obiektu. Operator -> języka
PHP:

$osoba->getImie()

zostaje w PHPTAL zastąpiony przez kropkę:

$osoba.getImie()

Klasa Osoba ma metody {stala}getImie(){/stala}, {stala}getNazwisko(){/stala},
{stala}getWiek(){/stala} oraz {stala}getPlec(){/stala}. Po przekazaniu do
szablonu tablicy obiektów klasy Osoba:

$template->osoby = OsobaPeer::doSelect(new Criteria);

stosujemy iterację {stala}tal:repeat{/stala}. W kolejnych obrotach
wywołujemy metody dostępu do pól obiektu o:


  
  
  
  
  

Oczywiście uruchomienie tego przykładu wymaga
instalacji bazy danych wypełnionej rekordami.
Zadanie to realizuje skrypt {stala}create-db-filled.bat{/stala}
(należy pamiętać o wprowadzeniu – w miejsce
AX1BY2CZ3 – hasła administratora).

Przykłady

ABBA

Pierwszy przykład, strona z piosenkami zespołu
ABBA, powstaje na podstawie plików tekstowych.
W skrypcie {stala}index.php{/stala} przetwarzamy pliki tekstowe.

Całość odczytanych informacji przekazujemy do szablonu
jako obiekt o nazwie menu – patrz listing 1.

class MenuItem
{
  public $url;
  public $caption;
    
  function __construct($aurl, $acaption)
  {
    $this->url = $aurl;
    $this->caption = $acaption;
  }
}

class Menu 
{
  private $ile;
  private $numer;
    
  public $tytul;
  public $tekst;
  public $piosenki;    
    
  function __construct()
  {
    $plik = file(\'dane/00lista.log\');
    $this->ile = count($plik);
   
    $this->numer = 0;
       
    if (isset($_GET[\'id\']) && str_ievpifr($_GET[\'id\'], 1, $this->ile)) {
      $this->numer = $_GET[\'id\'] - 1;
    }
        
    $tmp = explode(\':\', trim($plik[$this->numer]));
    $nazwaPlikuWybranego = $tmp[1];        
       
    $this->tytul = $tmp[0];
    $this->tekst = file_get_contents(\'dane/\' . $nazwaPlikuWybranego);        
        
    $this->piosenki = array();

    for ($i = 0; $i < $this->ile; $i++) {
      $linia = explode(\':\', trim($plik[$i]));
      $this->piosenki[$i] = new MenuItem(\'index.php?id=\' . ($i + 1), $linia[0]);
    }
  }
}

$template = new PHPTAL(\'templates/sz.html\');
$template->menu = new Menu;

try {
  echo $template->execute();
} catch (Exception $e){
  echo $e;
}

Obiekt ten ma następujące właściwości:

$menu->tytul
$menu->tekst
$menu->piosenki[]
$menu->piosenki[n]->url
$menu->piosenki[n]->caption

Dwie pierwsze właściwości, {stala}$menu->tytul{/stala} oraz
{stala}$menu->tekst{/stala}, zawierają dane piosenki wybranej
z menu. Właściwość {stala}$menu->piosenki[]{/stala} jest tablicą,
która zawiera wszystkie opcje menu. Każda
z opcji ma właściwość {stala}$menu->piosenki[n]->url{/stala}
oraz {stala}$menu->piosenki[n]->caption{/stala}. W szablonie
{stala}sz.html{/stala} najpierw ustalamy tytuł strony:

 ...

następnie drukujemy menu:

  1. ...

po czym wyświetlamy tytuł i tekst wybranej piosenki:

...

...

Ptaki

Drugi przykład jest bardziej skomplikowany. Witryna
\”Ptaki\” udostępnia zawartość bazy danych.
Całość jest zaimplementowana przy użyciu Propela.
Uruchomienie przykładu należy rozpocząć od
instalacji bazy danych. Zadanie to realizuje skrypt
zrzut-db.bat, w którym wystarczy wymienić hasło
administratora MySQL. Co ciekawe, wymiana systemu
Smarty na PHPTAL sprowadziła się do kilku
banalnych zmian w kodzie index.php.

Jak widać na listingu 2, wymieniona została
jedna instrukcja {stala}require_once{/stala}, instrukcje przekazujące
dane do szablonu oraz sposób wyświetlania
szablonu.

//require_once \'Smarty.class.php\';
require_once \'PHPTAL.php\';

...

case 4:
  $c = new Criteria;
  $c->addAscendingOrderByColumn(RodzinaPeer::RODZINA);    
  $rodziny = RodzinaPeer::doSelect($c);
//  $s->assign(\'rodziny\', $rodziny);
  $template->rodziny = $rodziny;
  break;    
    
...    

//$s->assign(\'akcja\', $akcja);
//$s->assign(\'folder\', $folder);
$template->akcja = $akcja;
$template->folder = $folder;


//$s->display(\'index.tpl\');
try {
  echo $template->execute();
} catch (Exception $e){
  echo $e;
}

Przygotowanie szablonu PHPTAL było znacznie
trudniejsze. W szablonie głównym index.html warunkowo
wywołujemy jedną z makrodefinicji zapisanych
w plikach {stala}home.html{/stala}, {stala}ptaki.html{/stala}, {stala}rodziny.html{/stala}, {stala}ptak.html{/stala}:






Każda z makroinstrukcji stosuje zmienne przekazane
do szablonu. Zmienne te są obiektami Propel
lub tablicami obiektów. Na przykład makroinstrukcja
rodziny.html/rodziny przetwarza tablicę
zawierającą obiekty klasy Rodzina. Obiekty te
mają metody:

  • {stala}getUrl(){/stala} – zwraca adres strony WWW
  • {stala}getRodzina(){/stala} – zwraca nazwę rodziny

Makrodefinicja przyjmuje więc postać:

Zmienna o nazwie {stala}$folder{/stala} jest konieczna z powodu
użycia względnych przyjaznych URL-i.

Zmienna osadzona w napisie

Zmienna może zostać osadzona w dowolnym napisie.
Treścią elementu HTML zostaje wówczas napis, w którym
występują zmienne. W skrypcie {stala}index.php{/stala} przekazujemy
do szablonu zmienną o nazwie cena:

$template->cena = \'659\';

Zmienna $cena zostaje osadzona w napisie
Cena wynosi … złotych przy użyciu modyfikatora
wyrażeń string:

...

Zmienne zawierające kod HTML

Należy pamiętać, że wartości zmiennych są przed
wydrukowaniem automatycznie zabezpieczane
wywołaniami {stala}htmlspecialchars(){/stala}. Jeśli do szablonu
przekażemy zmienną:

$template->tekst = \'

Lorem ipsum

\';

to znacznik:

...

spowoduje wydrukowanie tekstu, w którym znaki {html}<{/html} oraz {html}>{/html} są zastąpione przez {html}<{/html} i {html}>{/html}:

Lorem ipsum

Jeśli chcemy uniknąć konwersji kodu HTML, należy
skorzystać z modyfikatora structure:

...

Wówczas wygenerowany zostanie następujący
kod HTML:

Lorem ipsum

Przekształcanie zmiennych

Zmienne drukowane w szablonie mogą – przed
wydrukowaniem – być poddane dowolnym przekształceniom.
Modyfikacje wykonujemy wywołując
funkcje PHP. Najpierw przekazujemy do szablonu
zmienną o nazwie tytul:

$template->tytul = \'Lorem ipsum...\';

W szablonie stosujemy modyfikator php w połączeniu
z modyfikatorem structure:

...

...

Tablice asocjacyjne

W przypadku użycia tablic asocjacyjnych:

$t = array(\'imie\' => \'Andrzej\',\'nazwisko\' => \'Nijaki\');
$template->osoba = $t;

w szablonie stosujemy odwołania w postaci zmienna/
indeks, np.:

abc

abc

Rezygnacja ze znacznika

Niekiedy może się zdarzyć, że element PHPTAL wymusza
umieszczenie w kodzie HTML dodatkowych
znaczników. Instrukcja:

...

spowoduje wyświetlenie zmiennej tekst wewnątrz
znaczników {html}

{/html} i {html}

{/html}:

...treść zmiennej tekst...

W celu usunięcia elementu div z generowanego
kodu HTML należy użyć atrybutu tal:omit-tag:

...

W takiej sytuacji generowany kod HTML nie będzie
zawierał znaczników {html}

{/html} oraz {html}

{/html}.

Warunkowe przetwarzanie fragmentu szablonu

Rolę instrukcji if w szablonach PHPTAL pełni atrybut
{stala}tal:condition{/stala}. Jeśli zmienna liczba przekazana
do szablonu przyjmuje wartość logiczną true:

$template->liczba = 15;

wówczas treść elementu div pojawi się w wygenerowanym
kodzie HTML:

...

Atrybut {stala}tal:condition{/stala} może zawierać warunki
logiczne porównujące wartości zmiennych. W takim
przypadku operatory {html}<, <=, >{/html} oraz {html}>={/html} należy
zastąpić przez LT, LE, GT i GE odpowiednio, np.:

Lorem...
Pellentesque...

Iteracyjne przetwarzanie tablic

Pętla pojedyncza

Iteracyjne przetwarzanie tablic umożliwia atrybut tal:
repeat o składni przypominającej instrukcję foreach.
Do szablonu przekazujemy tablicę jednowymiarową.
Zmienna szablonu nazywa się owoce:

$t = array(\'malina\', \'wiśnia\');
$template->owoce = $t;

W szablonie umieszczamy atrybut {stala}tal:repeat{/stala}
o wartości owoc owoce:

  1. ...

Powoduje on przetworzenie wszystkich elementów
tablicy owoce. W poszczególnych obrotach
pętli do kolejnego elementu tablicy odwołujemy
się stosując nazwę owoc. Zapis:

tal:repeat=\"owoc owoce\" tal:content=\"owoc\"

jest analogiczny do:

foreach ($owoce as $owoc) {
  echo $owoc;
}

Indeksy obrotów pętli

Dostęp do indeksów pętli zapewniają specjalne odwołania
postaci:

repeat/x/index
repeat/x/number
repeat/x/even
repeat/x/odd
repeat/x/start
repeat/x/end

W miejsce x należy umieścić nazwę elementu
pętli, na przykład owoc:


  

Zmienne te mogą być osadzane w napisach
przy użyciu modyfikatora string. Oto w jaki sposób
możemy po numerze kolejnego elementu (dostępnego
jako repeat/owoc/number) dodać kropkę:


  ...
  ...

Pętla podwójna

Tablice dwuwymiarowe przetwarzamy w podwójnej
pętli {stala}tal:repeat{/stala}. Po przekazaniu do szablonu
zmiennej elementy:

$t = array(
  array(\'ala\', \'ola\', \'jola\', \'tola\'),
  array(\'marek\', \'jurek\'),
);
$template->elementy = $t;

stosujemy zagnieżdżoną pętlę tal:repeat:

Może cię też zainteresować

Internet Maker

PHP zdobył przed laty popularność jako język skryptowy do tworzenia stron internetowych. Wzięła się ona z pewnością stąd, że jeszcze kilka lat temu nie było alternatywy dla szybkiego, prostego...

Internet Maker

To już trzecie wydanie książki Andrzeja Kierzkowskiego, tłumaczącej nie tylko podstawy języka PHP 5, ale także zawierającej wiele praktycznych ćwiczeń. Autor od lat pisze książki dotyczące programowania w tym języku,...

Internet Maker

Język PHP jest wykorzystywany najczęściej do tworzenia skryptów pracujących na tekście. Jednak dzięki dołączonej do PHP bibliotece GD, możliwa jest łatwa praca na grafice – od prostej obróbki po rysowanie...

Internet Maker

Symfony to jeden z najlepszych dostępnych obecnie frameworków w języku PHP. Dzięki jasnej strukturze oraz generatorom kodu przygotowanie kompletnej aplikacji WWW zajmuje kilku minut. Artykuł opisuje krok po kroku...