Szablony w dzisiejszym świecie programowania są czymś niezbędnym - przekonywać do tego nie trzeba chyba nikogo. Dostępne są potężne narzędzia typu SMARTY które wspaniale radzą sobie z zadaniem oddzielenia treści od wyglądu oraz dają twórcom oprogramowania sporą dowolność jeśli chodzi o końcowy wygląd projektu. Jednak czy kombajn pokroju SMARTY podchodzący bardziej pod "nowy język" niż prosty "system szablonów" jest najlepszym wyjściem?
Postaram się wyjaśnić dlaczego na powyższe pytanie nie da się jednoznacznie odpowiedzieć i zaproponować prostą alternatywę.
Oczywiście porządny system szablonów sprawdza się wszędzie tam, gdzie wygląd strony może ulec zmianie, użytkownik powinien mieć w dzisiejszych czasach możliwość "przebrania" swojej treści w zupełnie nowe szaty, jednak czasem zdaża się, że zaprzęgnięcie do tego rozbudowanego systemu szablonów mija się z celem.
Kiedy użyć alternatywy? Jak zawsze należy podsumować kożyści wynikające z użycia danego rozwiązania, porównać z nakładami pracy, czasem poświęconym na wdrożenie i rozważyć wszelkie inne za i przeciw danego rozwiązania. Jeśli piszesz małą stronkę a'la wizytówka firmy, to może się okazać, że biblioteka obsługująca szablony będzie większa od całego projektu (objętościowo, ilość klass i funkcji - dowolne kryterium, które przyjdzie Ci do głowy. Wtedy warto pomyśleć nad alternatywnym rozwiązaniem. może użytkownik dostanie jedną lub dwie opcje mniej, ale przypominam mały projekt -> klient chce niewiele i czasem coś sobie pozmienia. jeśli zyski przewyższają straty myślimy o alternatywie.
Alternatywa:
zakładamy, że użytkownik robi sobie szablon wyglądający mniej więcej tak:
body.inc.tpl
<html>
<head>
<title>{$TITLE$}</title>
</head>
<body>
<ul id="nav">{$MENU$}</ul>
<div id="header"><h1>{$COMPANYNAME$}</h1><p>{$SLOGAN$}</p></div>
<div id="foot">{$FOOTERLINKS$}</div>
<div id="content">{$SITEBODY$}</div>
</body>
</html>
Prosty, czysty i czytelny - w rzeczywistości trochę trzeba by to dopracować, ale dla potrzeb tego artykułu wystarczy. To czego potrzebujemy to zamienić nasze {$COSIE$} na treść generowaną przez skrypt. W tym wypadku {$TITLE$}, {$MENU$}, {$COMPANYNAME$}, {$SLOGAN$}, {$FOOTERLINKS$} i {$SITEBODY$}.
te dane możemy pobrać z bazy czy pliku i stworzyć tablicę:
$dane=array(
'title' => 'Prosta strona',
'companyname' => 'Firma',
'slogan' => najlepsza firma w Twoim mieście',
'sitebody' =>'Hello world!',
'menu' => '',
'footerlinks' => ''
);
Zwróć uwagę, że nie mamy jeszcze $dane['menu'] oraz $dane['footerlinks']. To co wyciągamy z bazy trzeba "obrobić" tak, by nasz szablon ładnie wyglądał. dodajmy zatem kolejne dwa małe szablony: dla każdego elementu menu i dla każdego linku w stopce:
menu_item.inc.tpl
<li><a href="{$HREF$}">{$MENUITEM$}</a></li>
foot_item.inc.tpl
<a href="{$HREF$}">{$FOOTLINK$}</a>
może niezbyt wyszukany przykład, ale obrazuje nasz problem. teraz wystarczy pobrać z bazy odpowiednie dane i "stworzyć" brakujące zmienne:
foreach($dane_o_menu as $data) {
$dane['menu'].= template($data,'menu_item','mystyle');
}
foreach($dane_o_stopce as $data) {
$dane['menu'].= template($data,'foot_item','mystyle');
}
Użyłem w kodzie funkcji template, jej kod w listingu.
całość przepuścimy teraz przez nasz template i wyrzucimy wynik:
echo template($dane,'body','mystyle');
i tyle, cały "skrypt obsługi szablonu" mamy z głowy, proste, nieprawdaż. każdą "zmienną" w szablonie możemy przepuścić przez inny szablon pamiętając, że w odpowiedzi dostajemy już kod HTML.
Teraz conieco o strukturze katalogów. by było "profesjonalnie" tworzymy katalog:
./templates/
i do niego wrzucamy nasze style z rozszerzeniem .inc.tpl, np:
./templates/default/*.inc.tpl
./templates/mystyle/*.inc.tpl
poniżej kod funkcji template pobierającej tablicę z "zamiennikami", nazwę pliku szablonu (bez rozszerzenia) oraz nieobowiązkowo nazwę katalogu z szablonem i ścieżkę do zbioru szablonów.
Listing
function template($array, $template, $style="default", $path="./templates/"){
/*
Funkcja ta wczytuje szablon $template, a następnie podmienia dane przy pomocy tablicy
asocjacyjnej $array, gdzie indexem jest nazwa zmiennej
Następnie na podstawie listy, oczyszcza nieprzypisane zmienne
*/
$array['template_path']=$path.$style."/";
$tpl=file_get_contents($path.$style."/".$template.".inc.tpl"); //pobiera plik szablonu ze zmiennymi
foreach($array as $t => $content){
$tpl=str_replace("{\$".strtoupper($t)."\$}", $content, $tpl); //podmienia zmienne na wartości
}
$tpl=preg_replace('({\$(.*?)\$})', "", $tpl); //czyszczenie pozostałości
return $tpl; //zwraca gotowy kod html
}