PHP/Czym jest system szablonów?

< PHP
Poprzedni rozdział: Ćwiczenia

Czym jest system szablonów?

edytuj

W omówionych do tej pory zagadnieniach i przykładach milcząco zakładaliśmy, że nasz kod PHP bezpośrednio generował HTML dla przeglądarki. Pobierając dane z bazy natychmiast obudowywaliśmy je znacznikami i posyłaliśmy w świat. Jest to cecha charakteryzująca skrypty początkujących programistów PHP, która jednak rodzi dużo problemów z przenośnością i elastycznością tworzonego kodu. W następnych rozdziałach poznamy tzw. systemy szablonów, czyli biblioteki umożliwiające ich rozwiązanie.

Idea systemu szablonów

edytuj

Od poznania programowania obiektowego powoli przestajemy patrzeć na aplikację WWW jak na monolityczny blok, w którym wszystkie elementy są ściśle i nierozerwalnie ze sobą związane. Przekonaliśmy się już, że o wiele lepszym podejściem jest podział aplikacji na warstwy zajmujące się różnymi zadaniami i komunikujące między sobą. Przyjrzyjmy się zatem procesowi generowania kodu HTML. Opisując go możemy powiedzieć, że skrypt musi najpierw pobrać skądś dane, a następnie opakować je czymś, co umożliwi ich wyświetlenie w przeglądarce w zamierzony sposób. Wyraźnie widać tutaj dwa etapy, które - jak się okazuje - świetnie nadają się do rozdzielenia na dwie warstwy.

 
Zasada działania systemów szablonów.

System szablonów (ang. template engine) to biblioteka, która pozwala oddzielić warstwę prezentacji od logiki biznesowej. Podstawowym pojęciem jest tutaj szablon, czyli prosty plik tekstowy ze szkieletem wynikowego kodu HTML oraz zestawem instrukcji mówiących, co, gdzie i jak wyświetlić. Aplikacja WWW najpierw pobiera wszystkie dane, przetwarza je i umieszcza w systemie szablonów wraz z informacją o tym, jakiego szablonu użyć, jednak bez zwracania uwagi na szczegóły procesu wyświetlania. System szablonów wczytuje szablon i wykonuje go, osadzając w nim dane ze skryptu. Wynikiem jest gotowy kod, który jest posyłany do przeglądarki.

Systemy szablonów wykorzystywane są w zdecydowanej większości dużych projektów programistycznych nawet, jeśli nie są jawnie nazwane w ten sposób. Separacja pozwala na bardziej niezależny rozwój obu warstwy aplikacji oraz większą niezawodność; zajmując się algorytmami przetwarzania nie plączą nam się wokół wstawki kodu HTML, a pracując nad warstwą prezentacji nie ma obawy, że spowodujemy błąd w mechanizmach pobierania z bazy. Migracja na nową szatę graficzną sprowadza się do napisania nowych szablonów, a co więcej - możemy przechowywać kilka zestawów szablonów i dać użytkownikowi wybór, którego z nich chce użyć.

Nie odpowiedzieliśmy na jeszcze jedno cisnące się na usta pytanie - czym właściwie jest szablon? Jest to pewien plik tekstowy, rodzaj skryptu zawierający statyczny kod wysyłany do przeglądarki oraz reguły mówiące, jakie dane gdzie umieścić. Oczywiście do wyrażania tych reguł potrzebny jest jakiś dodatkowy meta-język i ze względu na niego możemy wyróżnić dwa główne rodzaje systemów szablonów:

  1. PHP jako język szablonów - reguły osadzania danych opisywane są przy pomocy zwykłych wstawek kodu PHP.
  2. Dedykowany język szablonów - system szablonów wprowadza specjalny język do zapisu reguł oraz dostarcza parser do jego przetwarzania.

Każde z rozwiązań ma swoje wady i zalety, które zaraz omówimy.

PHP jako język szablonów

edytuj

Przykładowy szablon napisany w PHP może wyglądać następująco:

<html>
 <head>
  <title><?=$title?></title>
 </head>
 <body>
  <?if($user == 'Adam'){?>
  Hello, <strong><?=$user?></strong>
  <?}else{?>
  Hello, <?=$user?>
  <?}?>
 </body>
</html>

Zamiast korzystania z konstrukcji <?php echo $zmienna;?>, użyliśmy tu krótszego odpowiednika dającego ten sam efekt, a mianowicie <?=$zmienna?>. Jednak aby takie rozwiązanie działało, musimy w pliku php.ini serwera ustawić short_open_tag na "on".

Korzystamy tutaj ze znanych nam już pętli, instrukcji warunkowych i zmiennych, co umożliwia bardzo szybkie wgryzienie się i wykorzystanie doświadczeń, które już znamy. Z drugiej strony czysty PHP poza pętlami i warunkami nie oferuje praktycznie nic rzeczywiście przydatnego do pisania dużej liczby szablonów i co więcej, bywa dość niewygodny. Dlatego systemy tego typu udostępniają dodatkowo pokaźny zbiór tzw. helperów, np. w postaci funkcji lub metod statycznych jakiejś klasy, które zamykają skomplikowane fragmenty kodu w prostym wywołaniu. Przykładowo, zamiast pisać skomplikowany kod do sklejania adresu URL z danych, możemy mieć funkcję link(), do której podamy jedynie argumenty i tytuł odnośnika, a od razu otrzymamy gotowy znacznik <a>.

Zalety:

  1. Prostota użycia - możemy wykorzystać doświadczenia, które już znamy.
  2. Potężna siła wyrazu - PHP to pełnoprawny język programowania, dlatego w szablonach możemy posługiwać się wszystkimi elementami składni do osiągnięcia żądanego celu.

Wady:

  1. Bez helperów praktycznie niezdatny do użycia na dłuższą metę. Ponadto same helpery są czasem wyjątkowo skomplikowane, szczególnie gdy próbujemy dostosować je do własnych potrzeb.
  2. Bardzo rozwlekła składnia i brak rozumienia struktury dokumentu HTML. Bez ścisłej dyscypliny bardzo łatwo stworzyć mocno nieczytelny kod.
  3. Bierzemy język PHP ze wszystkimi jego niekonsekwencjami, których nie mamy szansy zmienić i poprawić.

Dedykowany język szablonów

edytuj

Pod nazwą dedykowany język szablonów kryje się cała rodzina różnorodnych języków używanych przez różne systemy szablonów. Poniżej możemy zobaczyć przykład szablonu utworzonego w takim hipotetycznym języku:

<html>
 <head>
  <title>{TITLE}</title>
 </head>
 <body>
  {IF:USER == 'Adam'}
  Hello, <strong>{USER}</strong>
  {ELSE}
  Hello, {USER}
  {/IF}
 </body>
</html>

Cel przyświecający ich powstawaniu jest jeden: PHP jest zbyt nieczytelny, zbyt rozwlekły i ma zbyt dużo niekonsekwencji, by można było w nim łatwo tworzyć szablony, dlatego spróbujemy stworzyć coś lepszego, pozbawionego określonych wad. PHP powstał dlatego, że ktoś stwierdził, iż C czy C++ nie nadaje się na dłuższą metę do wygodnego tworzenia stron WWW. C i C++ powstały, gdyż uznano, że wygodniej jest pisać programy w ten sposób, niż w czystym assemblerze. Przykłady można mnożyć i analogiczna sytuacja ma miejsce tutaj. Czy się to udaje, zależy już od pomysłowości oraz umiejętności programisty tworzącego określony system. Teoretycznie tworząc własny język jesteśmy ograniczeni jedynie przez prawa fizyki i matematyki oraz przez własną wyobraźnię. W praktyce wiele z powstających języków ogranicza się głównie do udostępnienia wąskiego podzbioru PHP z <?php ?> zamienionym na klamerki, a w wielu popełniono równie poważne błędy projektowe, jak w PHP. Z tego właśnie powodu nie cieszą się one uznaniem części programistów patrzących przez pryzmat tych nieudanych prób.

Zalety:

  1. Dobrze zaprojektowany dedykowany język szablonów może być dużo efektywniejszy w użyciu, niż PHP.
  2. Możliwość pozbycia się wad i niedoróbek PHP, a także wielu detali technicznych, ukrywając je za prostymi konstrukcjami języka.

Wady:

  1. W praktyce rzadko kiedy to się udaje: brak umiejętności, pomysłowości, doświadczenia.
  2. Nawet jeśli konstrukcje języka są proste w użyciu, trzeba się ich najpierw nauczyć, zwłaszcza jeżeli odbiegają pod względem zasady działania od znanych już nam wzorców.

Kontrowersje

edytuj

Systemy szablonów to jedne z najbardziej kontrowersyjnych rodzajów bibliotek. W Internecie oraz w publikacjach można bardzo łatwo spotkać mnóstwo wzajemnie wykluczających się poglądów. Poniżej przedstawiony jest przegląd najważniejszych kontrowersji, argumentów krytyków oraz punktów widzenia, a także komentarz, jak będziemy traktować je w tym podręczniku.

Problem: PHP to system szablonów.

Wielu programistów nie stosuje rozróżnienia na systemy szablonów oraz języki szablonów, nazywając np. PHP systemem szablonów, albo degradując pojęcie systemu szablonów do języka. Powiedzieliśmy na początku, że system szablonów jest biblioteką, czyli zawiera jakieś klasy, funkcje, interfejsy, które umożliwiają przekazywanie danych z warstwy logiki do szablonów. PHP sam w sobie nic takiego nie posiada - dostarcza on pętli, instrukcji warunkowych, jakichś funkcji do przetwarzania danych, czyli ewidentnych narzędzi do pisania reguł i skryptów. Dopiero gdy dodamy do niego odpowiednie klasy i kod pozwalający uruchomić jakiś szablon z określonymi danymi, możemy mówić o systemie szablonów, natomiast bez tego jest to tylko język. W drugim kierunku sytuacja jest analogiczna. Język szablonów to jedynie sposób zapisu reguł osadzania danych, który bez odpowiedniego API nic nie znaczy.

W tym podręczniku będziemy konsekwentnie trzymać się zasady, że system szablonów to biblioteka, a język szablonów to język.

Problem: zawężanie pojęcia systemów szablonów do systemów z dedykowanym językiem.

Niektórzy programiści mówią, że nie używają systemów szablonów, lecz PHP, ponieważ nie widzą sensu w uczeniu się kolejnego języka. Przypomnijmy sobie, co powiedzieliśmy w poprzednim problemie - PHP to język szablonów, a nie system. Różnice w działaniu systemów szablonów korzystającego z PHP oraz ze swojego własnego języka sprowadzają się jedynie do tego, że w tym drugim przypadku trzeba szablony przetworzyć we własnym zakresie. Poza tym ich zasada funkcjonowania, zakres obowiązków i zadań jest dokładnie taki sam. Co więcej, PHP jest językiem takim, jak każdy inny. To, że akurat biblioteka jest też w nim napisana, nie wyróżnia go w żaden konkretny sposób - ostatecznie kompilator np. dla języka C pozostaje kompilatorem bez względu na to, w czym go napisano.

W tym podręczniku przyjmujemy zasadę: jeśli wygląda jak kaczka i kwacze jak kaczka, to jest to kaczka.

Problem: systemy szablonów to dodatkowa warstwa abstrakcji i dodatkowy narzut.

Odpowiedź na to pytanie wiąże się bezpośrednio z dwoma powyższymi podpunktami. System szablonów, a język szablonów to dwie różne rzeczy i nie należy ich mylić. Jeśli chcemy oddzielić warstwę logiki od warstwy prezentacji w aplikacji WWW, nie ma innego sposobu, jak użyć szablonów. Do przetwarzania szablonów zawsze potrzebny jest nam jakiś interfejs bez względu na to czy piszemy je w PHP czy w innym języku. Ponadto nie wolno na aplikację patrzeć nigdy jedynie przez pryzmat wydajności i narzutów tego czy innego elementu. Aplikacja w pierwszej kolejności ma spełniać określone wymagania i udostępniać określoną funkcjonalność. Jeżeli jednym z wymagań jest elastyczna budowa i podział na warstwy, wtedy ten dodatkowy narzut jest narzutem, który musimy ponieść, aby zrealizować cel.

W tym podręczniku przekonamy się, że każdy system szablonów to pewna warstwa abstrakcji bez względu na to, z jakiego języka korzysta oraz że są one powszechnie stosowane nawet, jeśli nie nazywają się systemami szablonów.

Problem: przetwarzanie dedykowanego języka szablonów jest niewydajne.

Argument ten jest słuszny jedynie w przypadku systemów szablonów, które od początku do końca zajmują się samodzielnie przetwarzaniem takiego języka. Sęk w tym, że takie systemy można policzyć na palcach jednej ręki. Prawie wszystkie istniejące obecnie systemy szablonów, które oferują swój własny język, korzystają z pewnej sztuczki: zamiast wykonywać szablon od zera, kompilują go do postaci... kodu PHP i wykonują. Co więcej, kompilacja wykonywana jest tylko wtedy, gdy zmieniony zostanie oryginalny szablon źródłowy; w przeciwnym wypadku używana jest od razu zapisana na dysku skompilowana wersja, dokładnie tak samo jak w systemach korzystających z PHP. Różnice w wydajności sprowadzają się tylko do tego, kto taki szablon PHP potrafi napisać lepiej: programista czy komputer, a to już zależy od konkretnej implementacji.

Zakończenie

edytuj

Dowiedzieliśmy się już, czym są systemy szablonów i dlaczego są one takie ważne. Pora przejść od teorii do praktyki. Na początku zilustrujemy to, co zostało tu powiedziane, próbując napisać prosty, edukacyjny system szablonów. Pomoże nam to zrozumieć zasadę działania i kryjące się za tym mechanizmy. Następnie pokażemy wybrane trzy systemy szablonów oraz sposób ich użycia.