PHP/Czym jest system szablonów?: Różnice pomiędzy wersjami

przebudowa rozdziału
m (poprawka nawigacji)
(przebudowa rozdziału)
 
== Czym jest system szablonów? ==
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.
Nastaje nowa era w dziejach. Koniec z umieszczaniem kodu HTML bezpośrednio w skryptach PHP. W tej części podręcznika zapoznasz się z systemami szablonów, które nie tylko pozwolą na odseparowanie tych dwóch elementów od siebie, ale również ułatwią wykonanie wielu dodatkowych zadań.
 
=== Idea systemu szablonów ===
Do tej pory wszystkie tworzone przez nas skrypty generowały zakodowany "na sztywno" w nich samych kod HTML. W przypadku większości zaprezentowanych tutaj przykładów nie stanowiło to zbyt dużego problemu, ale w większych projektach powstaje z tego powodu potężny zamęt. Gdyby przyszło nam wymieniać szatę graficzną, prawdopodobieństwo uszkodzenia jakiegoś algorytmu jest w takiej sytuacji spore.
 
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.
System szablonów (ang. ''template engine'' albo ''templating engine'') eliminuje tę niedogodność. Kod HTML jest przechowywany w osobnych, specjalnych plikach zwanych szablonami, w których odpowiednimi znacznikami oznaczone są miejsca, gdzie należy wstawić wyniki działania skryptu. Skrypt przetwarza dane, przekazuje je systemowi szablonów, a następnie wydaje polecenie przetworzenia żądanego szablonu. Parser ładuje szablon do pamięci, odnajduje w nim znaczniki, zamienia na dane ze skryptu, a rezultat wysyła do przeglądarki, gdzie internauta ogląda końcowy wynik. Wiele systemów szablonów nie poprzestaje na prostym osadzaniu danych - twórcy szablonów dostają do rąk zaawansowane narzędzia, niejednokrotnie o możliwościach normalnych języków programowania, a dodatkowe możliwości ułatwiają tworzenie np. list.
 
{{Definicja|'''Warstwa logiki biznesowej''' to warstwa aplikacji odpowiadająca za przetwarzanie, pobieranie i obróbkę danych. W jej skład wchodzą wszystkie operacje do komunikacji z plikami, bazami danych oraz algorytmy do przeprowadzania wszelkich obliczeń na danych.}}
System szablonów to normalna biblioteka napisana w PHP. Niemal zawsze posiada ona zorientowane obiektowo API. Istnieje wiele gotowych oraz porządnych systemów szablonów. Część z przytoczonych poniżej zalet oraz wad jest domeną tylko niektórych z nich. W tym podręczniku omawiać będziemy tylko dwa systemy szablonów: ''Smarty'' oraz ''Open Power Template'', na nich też poznamy praktyczne działanie tej kategorii skryptów.
 
{{Definicja|'''Warstwa prezentacji''' to warstwa aplikacji odpowiadająca za wyświetlenie (prezentację) danych użytkownikowi. To tutaj decydujemy, w jakim formacie wyświetlić dane, które z nich wyświetlić oraz jak je wyświetlić.}}
=== Zalety ===
Zalety systemów szablonów:
# '''Porządek w kodzie''' - HTML oddzielony od PHP.
# '''Automatyzacja''' - wiele systemów szablonów udostępnia specjalne znaczniki, które w prosty sposób pozwalają zrealizować skomplikowane zadania.
# '''Inna filozofia pracy''' - niektóre rzeczy łatwiej jest zrobić za pomocą systemu szablonów (np. obsługa formularzy).
# '''System cache''' - zaawansowane systemy szablonów potrafią przechowywać w plikach cache generowane wyniki, co zmniejsza obciążenie serwera i umożliwia obsłużenie większego ruchu.
# '''Inna organizacja pracy aplikacji WWW''' - dzięki systemom szablonów, nietrudno jest zbudować skrypt, który najpierw przetworzy wszystkie niezbędne dane, a dopiero na samym końcu zajmie się generowaniem wyniku HTML. Przy okazji umożliwia to większą dynamiczność aplikacji. Zauważmy bowiem, że przy wymieszanym kodzie HTML i PHP to, co już wysłaliśmy, jest wysłane i w razie jakichś problemów musimy zaakceptować ten smutny fakt. W przypadku systemu szablonów wystarczy jedynie zmienić szablon.
# '''Webmaster nie musi znać PHP''' - w wielu firmach grafik oraz programista to dwaj zupełnie różni ludzie i nie jest wcale powiedziane, iż muszą oni znać nawzajem swoje profesje. Dla webmastera tworzącego kod HTML zawiłości PHP mogą być trudne do przeskoczenia. Warstwa abstrakcji w postaci systemu szablonów separuje go od tego, oddając w jego ręce łatwy do zrozumienia zestaw narzędzi.
 
[[Plik:TempEngWeb017a_pl.svg|250px|thumb|Zasada działania systemów szablonów.]]
=== Krytyka ===
Część programistów PHP (i nie tylko) krytykuje systemy szablonów. Najważniejsze z przedstawianych przez nich argumenty to:
# ''Najlepszym systemem szablonów jest sam PHP'' - część systemów szablonów, o dziwo, korzysta z tego argumentu w całkiem praktyczny sposób. Zamiast samodzielnie zajmować się obsługą pętli, zwyczajnie kompilują one szablony do postaci kodu PHP, a później wykonują prosty '''include'''.
# ''Mitem jest, że system szablonów ułatwia pracę webmasterom. Zamiast jednego języka programowania (PHP) dostajemy inny, tyle że o innej składni.'' - jest to smutna prawda dotycząca części systemów szablonów. Udostępniane przez nie instrukcje są jedynie kalką tradycyjnych pętli oraz konstrukcji z klasycznych języków programowania. W takim przypadku faktycznie - stosowanie systemów szablonów nie ma zbyt wielkiego sensu. Pamiętajmy jednak, że są pozytywne wyjątki mające szereg instrukcji ukrywających programowanie przed webmasterem.
# ''Systemy szablonów zmniejszają wydajność'' - dotyczy to tylko części systemów szablonów. Jak wspomnieliśmy wyżej, najwydajniejsze kompilują szablony do postaci kodu PHP, a przy kolejnych wejściach wywołują jedynie prosty '''include''', uzyskując wydajność bardzo zbliżoną do zwykłego mieszania kodu HTML i PHP. Ponadto dużą rolę odgrywa tu odpowiednie z nich korzystanie. Nawet najlepszy parser, jeśli jest nieumiejętnie stosowany, może skutecznie "zarżnąć" serwer już przy małym obciążeniu.
 
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, jakie poznamy ===
W podręczniku tym omówimy dwa systemy szablonów: ''Smarty'' oraz ''Open Power Template''. Z pozoru opierają się na identycznym projekcie, ale w rzeczywistości prezentują nieco inne podejście do problemu szablonów. Zacznijmy od ich krótkiej charakterystyki.
 
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ży 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ć.
==== Smarty ====
''Smarty (TM)'' to jeden z najstarszych oraz bez wątpienia najpopularniejszy z dostępnych systemów szablonów, jego początki sięgają 2000 roku. Od tamtej pory przeszedł długą drogę, wzbogacony o nowe możliwości. Popularność oraz długa obecność sprawia dodatkowo, iż biblioteka jest bardzo stabilna i posiada bardzo małą liczbę błędów. Pomimo ogromnych możliwości, Smarty wygrywa wydajnościowo z wieloma mniej rozbudowanymi systemami szablonów. Dodatkowymi jego atutami są duża liczba materiałów pomocniczych (jego omówienie można znaleźć niemal w każdej bardziej zaawansowanej książce traktującej o PHP) oraz elastyczna architektura - łatwo rozszerzyć jego możliwości za pomocą rozszerzeń.
 
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:
Smarty posiada obiektową architekturę, ale ze względu na konieczność zachowania kompatybilności, jest skryptem pisanym i zoptymalizowanym głównie pod kątem należącego już do przeszłości PHP4. Wielu programistów zarzuca mu także zbytnie upodobnienie się do języka programowania oraz spychanie instrukcji automatyzujących złożone zadania na dalszy plan. Zastrzeżenia wysuwane są także pod adresem stylu nazewnictwa metod oraz samej składni szablonów, jednak jest to już jedynie kwestia gustu.
 
# '''PHP''' jako język szablonów - reguły osadzania danych opisywane są przy pomocy zwykłych wstawek kodu PHP.
Witryna Smarty: [http://smarty.net smarty.net]
# '''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.
==== Open Power Template ====
''Open Power Template'' to polski system szablonów zdobywający popularność głównie w naszym kraju. Jego początki datowane są na koniec 2004 roku, a obecny kształt przybrał na początku roku 2006. Jest on napisany oraz zoptymalizowany pod kątem PHP5 i nie działa na starszych wersjach. Głównym celem przyświecającym jego powstaniu było poprawienie i usunięcie wad systemu ''Smarty'', stąd też pewna liczba podobieństw występujących między tymi systemami (najprostsze szablony mogą być bez żadnych zmian przetwarzane przez oba). W Open Power Template instrukcje typowe dla języków programowania mają jednak charakter drugoplanowy, a znacznie większy nacisk położony został na bardziej wysokopoziomowe instrukcje rugujące programowanie z szablonów. Wydajność tego systemu jest minimalnie wyższa niż w Smarty.
 
=== PHP jako język szablonów ===
Open Power Template nie jest jednak tak popularny jak Smarty, co rzutuje na jakość dostępnych materiałów. Dokumentacja przechodzi okres poważnych zmian i natrafić można w niej na nieścisłości. Bardzo mało jest tekstów objaśniających wszystko krok po kroku, trudniej także uzyskać pomoc w przypadku napotkania problemów.
 
Przykładowy szablon napisany w PHP może wyglądać następująco:
Open Power Template jest częścią większego projektu: Open Power Board. W jego ramach opracowywany jest także dodatek do OPT zwany ''Open Power Forms'' zajmujący się obsługą formularzy, zaawansowany system kontroli danych oraz wsparcie dla AJAX.
 
<source lang="php" line><html>
Witryna Open Power Template: [http://opt.openpb.net opt.openpb.net]
<head>
<title><?php echo $title; ?></title>
</head>
<body>
<?php if($user == 'Adam'){ ?>
Hello, <strong><?php echo $user; ?></strong>
<?php }else{ ?>
Hello, <?php echo $user; ?>
<?php } ?>
</body>
</html>
</source>
 
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ę <code>link()</code>, do której podamy jedynie argumenty i tytuł odnośnika, a od razu otrzymamy gotowy znacznik <code>&lt;a&gt;</code>.
 
Zalety:
 
# Prostota użycia - możemy wykorzystać doświadczenia, które już znamy.
# 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:
 
# 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.
# Bardzo rozwlekła składnia i brak rozumienia struktury dokumentu HTML. Bez ścisłej dyscypliny bardzo łatwo stworzyć mocno nieczytelny kod.
# Bierzemy język PHP ze wszystkimi jego niekonsekwencjami, których nie mamy szansy zmienić i poprawić.
 
=== Dedykowany język szablonów ===
 
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 szablony utworzonego w takim ''hipotetycznym'' języku:
 
<source lang="html4strict" line><html>
<head>
<title>{TITLE}</title>
</head>
<body>
{IF:USER == 'Adam'}
Hello, <strong>{USER}</strong>
{ELSE}
Hello, {USER}
{/IF}
</body>
</html>
</source>
 
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 <code>&lt;?php ?&gt;</code> 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:
 
# Dobrze zaprojektowany dedykowany język szablonów może być dużo efektywniejszy w użyciu, niż PHP.
# Możliwość pozbycia się wad i niedoróbek PHP, a także wielu detali technicznych, ukrywając je za prostymi konstrukcjami języka.
 
Wady:
 
# W praktyce rzadko kiedy to się udaje: brak umiejętności, pomysłowości, doświadczenia.
# 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 ===
 
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 ===
 
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.
511

edycji