Template'y w PHP
Kod PHP przeplatający się z tagami HTML wygląda bardzo nieczytelnie. Jest
wiele metod na odseparowanie kodu PHP od kodu HTML. Można na przykład zrobić to
tak:
<?php function title() { echo 'tytuł'; }
function body() { table(); }
function table() { echo '<table>'; while (coś) { row(dane); } echo '</table>'; }
function row() { echo '<tr>'; echo '<td>'; echo ; echo '</td>'; echo '</tr>'; } ?>
<html> <head> <title><?php title() ?></title> </head> <body> <?php body() ?> </body> </html>
|
Mimo wszystko nie wygląda to najlepiej. Najepszym rozwiązaniem jest system
template'ów (wzorców). W systemie takim tworzone są osobne pliki zawierające
kod PHP i osobne zawierające kod HTML, zawierające jednak specjalne
oznaczenia, gdzie należy wstawić dane przekazane przez PHP. Taki plik może
przykładowo wyglądać tak:
<!-- plik "index.tpl" --> <html> <head> <title>{title}</title> <meta name="description" content="{description}"/> </head> <body> <table> <tr> <th>ID</th> <th>Autor</th> <th>Tytuł</th> <th>Wydawnictwo</th> </tr> {table} </table> </body> </html>
<!-- plik "table.tpl" --> <tr> <td> {id}. </td> <td> {autor} </td> <td> {tytul} </td> <td> {wydawnictwo} </td> </tr>
|
Na początek trzeba stworzyć klasę, która będzie przetwarzała wzorce. Trzeba
się zastanowić jakich metod i pól klasa będzie potrzebowała. Najwygodniej
będzie, jeśli konstruktor klasy będzie jako parametr przyjmował nazwę pliku
wzorca. Niezbędna będzie metoda dodająca zmienną do podstawienia (a co za tym
idzie także pole, w którym zmienne te będą przechowywane) oraz metoda
zwracająca przetworzony wzorzec. Dla wygody można także dodać metodę, która od
razu będzie wyświetlała wzorzec.
Tak więc na początek pola:
<?php class Template { var $tmpl; var $dane; } ?>
|
Konstruktor ma za zadanie wczytać plik ze wzorcem.
<?php function Template ($name) { $this->tmpl = implode('', file($name)); // Takie wczytanie pliku jest // bardzo szybkie $this->dane = Array(); } ?>
|
Funkcja dodająca dane do wzorca powinna przyjmować dane w dwóch postaciach:
albo dwa parametry - nazwa i wartość, albo jeden parametr - tablica, w której
nazwy zmiennych zapisane są jako klucze.
<?php function add($name, $value = '') { if (is_array($name)) { $this->dane = array_merge($this->dane, $name); } else if (!empty($value)) { $this->dane[$name] = $value; } } ?>
|
Powyższa metoda sprawdza, czy pierwszy z parametrów jest tablicą. Jeśli tak,
zostaje ona dołączona do istniejących danych przy pomocy funkcji
array_merge(). Podawanie do metody tablicy jest bardzo wygodne -
umożliwia to bezpośrednie przekazanie wiersza odczytanego z bazy danych. Jeśli
natomiast podane zostały dwa parametry, pierwszy z nich zostanie użyty jako
klucz a drugi jako wartość tablicy z danymi.
Skoro są już dane i jest wzorzec, trzeba to połączyć, czyli stworzyć metodę
wstawiającą dane do wzorca. Można to zrobić na wiele sposobów. Seria wywołań
funkcji str_replace jest nieefektywna, gdyż dla każdego wywołania wzorzec musi
być przeszukany od początku - dużo lepiej jest zrobić to przy pomocy
wyrażeń regularnych. Przy pomocy funkcji preg_replace() można podmienić
każde napotkane wyrażenie {zmienna} na zawartość tablicy o kluczu podanym w
wyrażeniu.
<?php function execute() { return preg_replace('/{([^}]+)}/e', '$this->dane["\\1"]', $this->tmpl); } ?>
|
Teraz wystarczy posklejać wszystko w całość.
<?php class Template { var $tmpl; var $dane;
function Template ($name) { $this->tmpl = implode('', file($name)); $this->dane = Array(); }
function add($name, $value = '') { if (is_array($name)) { $this->dane = array_merge($this->dane, $name); } else if (!empty($value)) { $this->dane[$name] = $value; } }
function execute() { return preg_replace('/{([^}]+)}/e', '$this->dane["\\1"]', $this->tmpl); }
} ?>
|
Teraz może mały przykład jak to wykorzystać. Zakładając, że klasa Template
znajduje się w pliku template.inc.php:
<!-- plik test.php --> <?php include 'template.inc.php';
$tmpl = new Template('test.tmpl'); $tmpl->add('title', 'strona testowa'); $tmpl->add('autor', 'Leszek'); $tmpl->add('charset', 'iso-8859-2'); $dane = Array('imie'=> 'Franek', 'podpis'=>'sincerly yours'); $tmpl->add($dane); echo $tmpl->execute();
?> <!-- plik test.tmpl --> <html> <head> <title>{title}</title> <meta http-equiv="Content-type" content="text/html; charset={charset}" /> </head> <body> <p>Cześć, nazywam się {autor}</p> <p>To jest indywidualna strona stworzona tylko dla Ciebie, {imie}</p> <p>{podpis}</p> <p style="text-indent: 30ex">{autor}</p> </body> </html>
|
System taki można także zagnieżdżać, aby wyświetlać dane z tabeli.
<!-- plik test.php --> <?php include 'template.inc.php';
$res = mysql_query('select * from data'); while($row = mysql_fetch_array($res)) { $rows = new Template('rows.tmpl'); $rows->add($row); $table .= $rows->execute(); }
$tmpl = new Template('test.tmpl'); $tmpl->add('title', 'strona testowa'); $tmpl->add('charset', 'iso-8859-2'); $tmpl->add('table', $table); echo $tmpl->execute();
?> <!-- plik test.tmpl --> <html> <head> <title>{title}</title> <meta http-equiv="Content-type" content="text/html; charset={charset}" /> </head> <body> <table> {table} </table> </body> </html> <!-- plik rows.tmpl --> <tr> <td> {imie} </td> <td> {nazwisko} </td> <td> {adres} </td> </tr>
|
Przy użyciu tego systemu wzorców zmiana sposobu wyświetlania danych z bazy
danych z tabelarycznego na rekordowy to kwestia usunięcia otwarcia tabeli z
głównego wzorca i zmiany wzorca wyświetlającego dane.
Rozwiązanie to jest bardzo proste, ale wystarcza dla wielu celów.
Zaawansowane systemy wzorców, takie jak na przykład Smarty, umożliwiają
umieszczenie we wzorcach pętli. Dodanie takich opcji wymaga już innej
konstrukcji funkcji podstawiającej dane do wzorca oraz samego wzorca.
Niezbędne jest określenie bloku, który będzie podlegał pętli, oraz danych -
najłatwiej podać je w postaci tablicy. Jak to zrealizować - najepiej podejrzeć
jak jest to zrealizowane w innych systemach.
Jeśli potrzebny jest system wzorców oferujący większe możliwości, można
skorzystać z gotowych rozwiązań. Jednym z najlepszych pakietów jest Smarty
Templates, dostępny pod adresem http://smarty.php.net/
Podstawianie danych do wzorca i wyświetlanie go za każdym żądaniem od klienta
jest nieefektywne - operacja podstawiania jest stosunkowo długotrwała a
potrzeba ponownego generowania strony zachodzi tylko w dwóch przypadkach:
kiedy zmienia się wzorzec albo zmieniają się dane. Dobrym rozwiązaniem jest
zastosowanie klas typu Cache - jednej z dostępnych (np. zawartej w
repozytorium PEAR - http://pear.php.net) lub napisanie własnej (o tym w
osobnym artykule).
| Wasze opinie: |
| Średnia ocena: 3.88/10 (397 głosów) |
|
| Liczba komentarzy: 56699 (pokaż wszystkie) | Skomentuj !
|
| Autor: ? | Data dodania: 2011-03-11 |
| Fajne komentarze... forum php, a tyle spamu... :? |
|
|