Szablony Smarty Pakiet Smarty jest obiektową biblioteką służącą do tworzenia serwisów internetowych w języku php techniką szablonów. Główna klasa zawarta w bibliotece nazywa się Smarty i realizuje przetwarzanie szablonu w stronę WWW. Podstawowa funkcjonalność każdego systemu szablonów polega na podstawieniu w miejsce zmiennych szablonu wartości ustalonych przez część logiczną aplikacji. Oprogramowanie Smarty oprócz zwykłej zamiany zmiennych umożliwia umieszczenie w szablonie instrukcji sterujących. Szablon może zawierać iteracje section oraz instrukcje if zagnieżdżone dowolną liczbę razy. Ponieważ wyrażenia stanowiące warunki instrukcji if są kompilowane do postaci php, zatem mogą one być dowolnie skomplikowane. Bardzo mocną stroną systemu Smarty jest jego wydajność, osiągnięta dzięki wbudowanemu systemowi cache. Niemal wszystkie wyniki porównania wydajności są zgodne, że Smarty jest najwydajniejszym dostępnym obecnie oprogramowaniem przetwarzania szablonów. Efektywność systemu Smarty wynika między innymi z zastosowanej techniki przetwarzania szablonu. Szablon jest kompilowany do kodu php i zapisywany w skompilowanej postaci. Kompilacja odbywa się jeden raz, zaś wszystkie późniejsze odwołania wykorzystują wersję skompilowaną szablonu. Ponowna kompilacja ma miejsce jedynie wówczas, gdy pliki szablonu ulegną zmianie. Język opisu szablonu jest rozszerzalny i może być wzbogacany o nowe funkcje. Smarty wykorzystuje technikę wtyczek, dzięki czemu dołączanie własnego kodu do biblioteki nie jest skomplikowane. Instalacja i uruchomienie Na stronie domowej projektu Smarty znajdziemy między innymi dokumentację oraz najnowszą wersję oprogramowania. http://www.smarty.net/ Po rozpakowaniu pliku z systemem smarty na dysk twardy należy dokonać zmian w pliku konfiguracyjnym php.ini. Katalog zawierający pliki biblioteki Smarty musi być dostępny w ścieżkach poszukiwań php. Jeśli plik został rozpakowany do folderu C:\php\smarty, wówczas w pliku php.ini należy zmodyfikować zmienną konfiguracyjną include_path nadając jej wartość include_path = ".;c:\php\smarty\libs" Wówczas dołączanie biblioteki Smarty do skryptu nie wymaga podania pełnej ścieżki dostępu. Jeśli z jakichkolwiek powodów nie możemy zmieniać pliku php.ini, wówczas należy stosować pełną ścieżkę przy dołączaniu biblioteki do skryptu.
Smarty - składnia szablonu Szablon Smarty jest plikiem tekstowym zawierającym znaczniki HTML oraz znaczniki szablonu. Znaczniki szablonu są otoczone nawiasami klamrowymi <P>...kod strony...</p> {$znaczniksmartyphp} <P>...kod strony...</p> {#znaczniksmartyconfig#} <P>...kod strony...</p> {funkcjasmarty} Każdy ze znaczników szablonu Smarty powoduje albo wydrukowanie wartości zmiennej albo wywołanie funkcji. {$znaczniksmartyphp} drukuje na wyjściu wartość zmiennej $znaczniksmartyphp pochodzącej ze skryptu php. Podobnie, znacznik {#znaczniksmartyconfig#} powoduje wydrukowanie zmiennej #znaczniksmartyconfig# odczytanej z pliku konfiguracyjnego. Wreszcie znacznik {funkcjasmarty} wywołuje funkcję funkcjasmarty. Zmienne pochodzące ze skryptu php rozpoczynają się znakiem dolara, zmienne konfiguracyjne są otoczone haszmarkami, brak znaków dolara i haszamarków oznacza, że znacznik szablonu jest wywołaniem funkcji. Część znaczników stanowiących wywołanie funkcji posiada znaczniki zamykające poprzedzone - podobnie jak znaczniki zamykające HTML - znakiem slash {funkcjasmarty}..zawartość... {/funkcjasmarty} Ostatni możliwy znacznik Smarty {* dowolny tekst *} jest komentarzem w szablonie. Domyślna składnia szablonów Smarty wykorzystuje nawiasy klamrowe do oznaczenia zmiennych oraz funkcji. Nawiasy te możemy zastąpić dowolnymi innymi napisami, na przykład {{ oraz }} lub <!--{ oraz }-->. Powodem, dla którego może okazać się to konieczne jest chęć stosowania wewnętrznych arkuszy stylów w szablonie.
Pierwszy skrypt Pracę nad pierwszym skryptem rozpoczynamy od utworzenia drzewa katalogów. W folderze 01- smarty, w którym umieścimy skrypt, zakładamy dwa foldery templates oraz templates_c. Katalog templates będzie zawierał szablony stron, zaś katalog templates_c służy do przechowywania skryptów skompilowanych przez system Smarty. Przykład pierwszy składa się z dwóch plików: index.php oraz index.tpl. Skrypt index.php zawiera kod przetwarzający szablon zapisany w pliku index.tpl. Skrypt wykorzystujący system Smarty rozpoczynamy od dołączenia pliku Smarty.class.php require_once 'Smarty.class.php'; Następnie tworzymy obiekt będący egzemplarzem klasy Smarty $smarty = new Smarty; Do przypisania wartości zmiennym szablonu służy funkcja assign. Jej pierwszym parametrem jest nazwa zmiennej szablonu, zaś drugim przypisywana wartość. $smarty -> assign('tytul', 'Witaj!'); $smarty -> assign('tresc', 'Pierwsza strona stosująca szablony Smarty!'); Po dokonaniu podstawienia wartości zmiennych strona WWW jest wysyłana do klienta. Metoda display klasy Smarty wczytuje szablon z pliku, którego nazwa jest parametrem, następnie przetwarza szablon dokonując podstawienia zmiennych, po czym wysyła otrzymany kod HTML do klienta $smarty -> display('index.tpl'); Powyższe instrukcje stanowią zawartość pliku index.php. Szablon zapisany w pliku index.tpl zawiera dwie zmienne {$tytul} oraz {$tresc}. Zmienne przekazane do szablonu Smarty ze skryptu php metodą assign są otoczone nawiasami klamrowymi i poprzedzone znakiem dolara <html> <title>{$tytul}</title> <body> <p>{$tresc}</p> </body> </html> Po uruchomieniu przykładu powinniśmy zobaczyć w przeglądarce stronę WWW o tytule Witaj i treści Pierwsza strona stosująca szablony Smarty.
Jeśli pracujemy w systemie Unix/Linux, wówczas może się okazać koniecznym nadanie uprawnienia w do folderu template_c dla pozostałych użytkowników chmod o+w tempate_c Modyfikatory zmiennych Zmienne szablonu możemy poddać procesowi przetwarzania wykorzystując tzw. modyfikatory zmiennych. Każdy z modyfikatorów (domyślnie jest ich 21) stanowi pewnego rodzaju procedurę konwertującą napis będący argumentem. Wywołanie modyfikatora ma postać {$zmienna modyfikator} Na przykład zamianę małych liter na duże realizuje modyfikator upper. Przekształcenie zmiennej $tresc tak by zawierała jedynie duże litery sprowadza się do polecenia {$tresc upper} Przekształcenie odwrotne realizuje modyfikator lower {$tresc lower} Wszystkie standardowe modyfikatory zmiennych lp. Modyfikator Działanie 1. capitalize, zamiana liter w napisie lower, upper 2. count_characters, zliczanie znaków, akapitów, słów oraz zdań count_paragraphs, count_words, count_sentences 3. cat złączanie napisów 4. date_format formatowanie daty 5. default ustalenie wartości domyślnej zmiennej 6. escape cytowanie znaków specjalnych w napisie 7. indent wcięcia akapitów 8. nl2br konwersja znaku złamania wiersza \n na znak <br /> 9. replace, zamiana napisów oraz wyrażeń regularnych regex_replace 10. spacify rozstrzelenie napisu 11. string_format formatowanie napisu 12. strip, usuwanie białych znaków oraz znaków strip_tags 13. truncate skracanie długości napisu 14. wordwrap łamanie wierszy w napisie
Modyfikatory możemy ze sobą łączyć. Umieszczenie kilku modyfikatorów po nazwie zmiennej spowoduje, że zmienna zostanie poddana kolejno kilku transformacjom. Na przykład zastosowanie modyfikatorów nl2br oraz upper {$tresc nl2br upper} spowoduje, że po pierwsze znaki złamania wiersza zostaną zastąpione znacznikami <br>, a następnie wszystkie litery w otrzymanym napisie będą zastąpione dużymi odpowiednikami. Oczywiście kolejność stosowania modyfikatorów jest istotna. W powyższym przykładzie, modyfikator upper zamieni zarówno litery oryginalnego napisu jak i znaczników <br>. Niektóre spośród modyfikatorów przyjmują dodatkowe parametry. W takim przypadku parametry należy podać bezpośrednio po modyfikatorze oddzielając je znakiem dwukropka. Przykładami modyfikatorów posiadających parametry są truncate oraz wordwrap. Modyfikator truncate usuwa z napisu końcowe znaki, w taki sposób, że napis wynikowy nie przekracza zadanej długości. Parametrami modyfikatora są liczba znaków, do jakiej napis ma zostać skrócony oraz opcjonalny tekst dodawany na końcu napisu. Zastosowanie modyfikatora ma postać {$tresc truncate:90:"... "} Podobnie, stosując modyfikator wordwrap podajemy dwa parametry {$tresc wordwrap:30:"<br>"} Modyfikator wordwrap łamie wiersze w taki sposób, że w wynikowym napisie żadna linijka nie przekracza zadanej liczby znaków. Maksymalna liczba znaków w linii oraz napis dodawany na końcu każdej linii są parametrami modyfikatora. Zmienne tablicowe w szablonie Prosta zamiana napisów w szablonie na wartości wyznaczone przez skrypt nie umożliwia całkowitej separacji silnika aplikacji od oprawy graficznej. Problemy pojawią się na przykład wówczas, gdy na stronie chcemy umieścić tabelkę zawierającą informacje przechowywane w tablicy php. Jeśli chcemy usunąć zupełnie kod HTML ze skryptu php, wówczas konieczne staje się użycie w szablonie pętli. Przeanalizujmy następujący kod php $tplcars = array( 'Ford', 'Opel', 'Fiat', 'BMW', 'Mercedes', 'Renault', 'Citroen', 'Volkswagen' ); $smarty -> assign('cars', $tplcars); W skrypcie tym tworzymy nową zmienną tablicową o nazwie $tplcars, która zawiera nazwy marek samochodów. Tablica ta jest następnie przekazana do szablonu jako zmienna $cars. Naszym celem jest przygotowanie szablonu w taki sposób, aby każda marka stanowiła osobny wiersz tabeli HTML. Szablon po odebraniu zmiennej $cars musi przetworzyć ją element po elemencie i wyprodukować na wyjściu jeden wiersz tabelki HTML dla każdego elementu tablicy $cars.
Szablon stanowiący rozwiązanie zawiera tabelę HTML, wewnątrz której znajduje się pętla <table> {section name=car loop=$cars} <tr><td>{$cars[car]}</td></tr> {/section} </table> Pętla przetwarzająca tablicę w szablonach Smarty jest definiowana przez funkcję section. Znacznik {section...} otwiera, zaś {/section} kończy pętlę. Kod HTML umieszczony pomiędzy dwoma znacznikami section będzie powtórzony dla każdego elementu tablicy $cars. Przyjrzyjmy się parametrom funkcji section. Parametr name ustala nazwę zmiennej sterującej. Wewnątrz pętli wartość parametru name (w przykładzie: car) stanowi licznik obrotów pętli. Drugim wymaganym parametrem funkcji section jest loop. Wartością tego parametru jest tablica, względem której dokonujemy iteracji. Do elementów tablicy $cars odwołujemy się podając indeks car $car[car] Należy zwrócić baczną uwagę na parametry przekazywane pomiędzy skryptem a szablonem. W przykładzie jest to tablica zawierająca wyrazy Ford, Opel itd. W skrypcie nie występują żadne znaczniki HTML, zaś do komunikacji skryptu z szablonem stosujemy "surową" tablicę. Jest to jedno z najważniejszych przykazań warunkujących efektywne stosowanie szablonów. Zaawansowane możliwości sekcji Funkcja section posiada, poza omówionymi parametrami name oraz loop, dodatkowe parametry przedstawione w tabeli poniżej. Parametry te umożliwiają zmianę porządku przetwarzania tablicy jak również ograniczenie liczby obrotów pętli. Parametry funkcji section lp. Atrybut Typ Wymagany Wartość Opis domyślna 1. name string tak - nazwa sekcji 2. loop nazwa tak - nazwa zmiennej, która wyznacza liczbę obrotów pętli zmiennej 3. start integer nie 0 numer, od którego rozpocznie się pętla (wartość ujemna powoduje wyznaczenie numeru względem końca) 4. step integer nie 1 krok, o jaki zmieniamy wartość licznika w kolejnych obrotach pętli (wartość ujemna spowoduje przetwarzanie tablicy od końca do początku) 5. max integer nie 1 maksymalna liczba faktycznie wykonanych obrotów pętli 6. show boolean nie true wartość false powoduje, że sekcja nie zostanie w ogóle wykonana
Jeśli chcemy przetworzyć elementy tablicy zawierającej marki samochodów od elementu drugiego i uwzględniając co trzecią pozycję, wówczas wystarczy ustalić wartość atrybutu start=1 oraz step=3. Pamiętajmy, że elementy tablicy są numerowane od 0. Pierwszy element ma numer 0, drugi - 1, trzeci - 2, itd. {section name=car loop=$cars start=1 step=3} Jeśli tablica przekazana do szablonu zawierała następujące napisy Ford Opel Fiat BMW Mercedes Renault Citroen Volkswagen wtedy na wydruku wyprodukowanym przez sekcję pojawią się marki Opel (indeks: 1) Mercedes (indeks: 4 = 1 + 3) Volkswagen (indeks: 7 = 4 + 3) Jeśli chcemy przetworzyć elementy tablicy od ostatniego do pierwszego, wówczas wartość obu parametrów start i step powinna być równa -1 {section name=car loop=$cars start=-1 step=-1} Wydruk w tym przypadku zawierałby wszystkie marki w odwrotnej kolejności Volkswagen Citroen Renault Mercedes BMW Fiat Opel Ford Ustalając wartość atrybutu max ograniczamy liczbę faktycznie wydrukowanych wierszy. {section name=car loop=$cars max=3} Wartość 3 spowoduje, że na stronie WWW widoczne będą trzy pierwsze marki samochodów: Ford, Opel oraz Fiat. Natomiast wartość parametru show równa false spowoduje, że dana sekcja nie wyprodukuje żadnych wyników, bez względu na wartości pozostałych parametrów {section name=car loop=$cars start=2 step=2 show=false} Oprócz parametrów, sekcja może posiadać opcjonalny fragment {sectionelse}
{section...}...iteracja... {sectionelse}...jeśli iteracja była pusta... {/section} Treść szablonu umieszczona pomiędzy znacznikami {sectionelse} oraz {/section} będzie zawarta w stronie wynikowej wówczas, gdy żaden spośród elementów tablicy nie zostanie przetworzony przez iterację. Zmienne sekcji Oprócz atrybutów określanych w znaczniku otwierającym, sekcje posiadają również zmienne, dzięki którym mamy dostęp do informacji dotyczących numeru obrotu pętli. Typowym przykładem zastosowania zmiennych sekcji jest numeracja wierszy tabeli HTML. Składnia dostępu do zmiennych sekcji jest następująca {$smarty.section.nazwasekcji.nazwazmiennej} Nazwa sekcji jest równa wartości atrybutu name danej sekcji, zaś nazwa zmiennej jest jedną spośród dziesięciu dostępnych zmiennych. Zmienne sekcji lp. Nazwa Funkcja zmiennej 1. index Indeks przetwarzanego elementu tablicy. Pierwszy element ma numer 0 lub jest równy parametrowi start. Wartość zmiennej index jest zwiększana zgodnie z wartością atrybutu step. 2. index_prev Indeks poprzedniego elementu w tablicy. Zmienna ta uwzględnia parametr step. 3. index_next Indeks następnego elementu w tablicy. Zmienna ta uwzględnia parametr step. 4. iteration Numer obrotu pętli. Numeracja rozpoczyna się od 1 i jest zwiększana o jeden wraz z każdym przebiegiem iteracji. 5. first Wartość logiczna równa true tylko wówczas, gdy bieżącym jest pierwszy obrót pętli. 6. last Wartość logiczna równa true tylko wówczas, gdy bieżącym jest ostatni obrót pętli. 7. loop Wartość równa indeksowi ostatniego elementu tablicy. 8. total Wartość równa liczbie faktycznie przetworzonych elementów. Zmienne sekcji są przydatne między innymi przy numeracji wierszy tabeli jak również umożliwiają wyświetlanie liczby przetworzonych elementów tabeli. Poniższe rysunki przedstawiają wartości wszystkich zmiennych sekcji przetwarzających tablicę marek samochodów z poprzedniego przykładu. Pierwsza z ilustracji przedstawia wynik działania sekcji o parametrach start=3 step=2, zaś druga start=-1 step=-1.
Jeśli chcemy ponumerować wiersze tabeli oraz umieścić informację o liczbie faktycznie wyświetlonych wierszy, wówczas należy skorzystać ze zmiennych total oraz iteration. Poniższy szablon realizuje to zadanie <table border="1"> <tr> <td>lp.</td> <td>marka</td> </tr> {section name=car loop=$cars} <tr> <td>{$smarty.section.car.iteration}</td> <td>{$cars[car]}</td> </tr> {/section} </table> <p> liczba samochodów: {$smarty.section.car.total}. </p>
Wiele tablic oraz tablice wielowymiarowe Zastanówmy się, w jaki sposób przekazać do szablonu dane odczytane z pliku tekstowego. Plik nagrodynobla.txt zawiera informacje na temat nagród Nobla. Każdy wiersz opisuje jeden rok. Dane na temat kolejnych dziedzin są oddzielone dwukropkiem Za rok:fizyka:chemia:fizjologia i medycyna:... 1901:W.C. Roentgen (N):J.H. van't Hoff (Hol):... 1902:H.A. Lorentz (Hol),P. Zeeman (Hol):...... Zadanie to można rozwiązać na cztery nieco odmienne sposoby: stosując sześć niezależnych tablic, stosując jedną "poziomą" tablicę wielowymiarową, stosując jedną "pionową" tablicę wielowymiarową, stosując jedną asocjacyjną tablicę wielowymiarową. W zależności od konkretnej sytuacji, pewne z tych rozwiązań mogą być bardziej korzystne od innych. Iteracja wielu tablic Pierwszym najbardziej oczywistym podejściem jest utworzenie osobnej tablicy dla każdej kolumny danych zapisanej w pliku. W skrypcie przedstawionym na listingu 1 tworzymy sześć tablic $rok, $fizyka, $chemia, $medycyna, $literatura, $pokojowa, a następnie dodajemy do nich wartości odczytane z pliku. Tak ustalone tablice przekazujemy do szablonu sześciokrotnie wywołując metodę assign. Główną wadą takiego podejścia jest to, że powiązane ze sobą informacje przechowujemy w osobnych zmiennych. W ten sposób liczba różnych zmiennych występujących w skrypcie niepotrzebnie wzrośnie. Przetwarzanie wielu tablic w szablonie ilustruje listing 1. Do wyznaczenia liczby obrotów sekcji stosujemy dowolną z tablic (wszystkie tablice posiadają identyczną liczbę elementów), na przykład $rok. Wewnątrz sekcji odwołujemy się do każdej z tablic przekazując indeks sekcji. Odwołanie do tablicy $fizyka ma postać <TD>{$fizyka[nagrody]}</TD>
Listing 1. Skrypt przekazujący do szablonu sześć tablic. <?php $rok = array(); $fizyka = array(); $chemia = array(); $medycyna = array(); $literatura = array(); $pokojowa = array(); $plik = file('nagrodynobla.txt'); $tmpcount = count($plik); for ($i = 0; $i < $tmpcount; $i++) { $linia = explode(':', trim($plik[$i])); $rok[] = $linia[0]; $fizyka[] = $linia[1]; $chemia[] = $linia[2]; $medycyna[] = $linia[3]; $literatura[] = $linia[4]; $pokojowa[] = $linia[5]; } $smarty = new Smarty; $smarty -> assign('rok', $rok); $smarty -> assign('fizyka', $fizyka); $smarty -> assign('chemia', $chemia); $smarty -> assign('medycyna', $medycyna); $smarty -> assign('literatura', $literatura); $smarty -> assign('pokojowa', $pokojowa); $smarty -> display('index.tpl');?> Listing 2. Szablon stosujący sześć tablic. {section name=nagrody loop=$rok} <TR> <TD>{$rok[nagrody]}</TD> <TD>{$fizyka[nagrody]}</TD> <TD>{$chemia[nagrody]}</TD> <TD>{$medycyna[nagrody]}</TD> <TD>{$literatura[nagrody]}</TD> <TD>{$pokojowa[nagrody]}</TD> </TR> {/section}
Tablica "pionowa" Niewielkim kosztem możemy wyeliminować wadę pierwszego rozwiązania. Jeśli sześć tablic $rok, $fizyka, $chemia, $medycyna, $literatura, $pokojowa wstawiamy do jednej tablicy $tabela $tabela = array( $rok, $fizyka, $chemia, $medycyna, $literatura, $pokojowa ); wtedy przekazanie kompletu danych do szablonu będzie wymagało jednokrotnego wywołania metody assign. Wszystkie informacje są przechowywane w jednej tablicy dwuwymiarowej. Tablicę taką nazwiemy "pionową", gdyż jej współrzędne zawierają kolumny danych. Na przykład wszyscy fizycy są przechowywani w tablicy $tabela[1], zaś pisarze w tablicy $tabela[4]. Tablice pionowe okażą się bardzo wygodne przy stosowaniu funkcji dotyczących list wyboru. Listing 3. Szablon stosujący tablicę "pionową". {section name=nagrody loop=$tabela[0]} <TR> <TD>{$tabela[0][nagrody]}</TD> <TD>{$tabela[1][nagrody]}</TD> <TD>{$tabela[2][nagrody]}</TD> <TD>{$tabela[3][nagrody]}</TD> <TD>{$tabela[4][nagrody]}</TD> <TD>{$tabela[5][nagrody]}</TD> </TR> {/section} Szablon przetwarzający tablice wielowymiarową $tabela jest widoczny na listingu 3. Zmienną wyznaczająca ilość obrotów sekcji jest pierwsza współrzędna tablicy (zawierająca lata) loop=$tabela[0]. Natomiast do elementów tablicy odwołujemy się, podobnie jak w php, za pomocą dwukrotnie użytych nawiasów kwadratowych <TD>{$tabela[0][nagrody]}</TD> Tablica "pozioma" Tablica "pozioma", tym się różni od pionowej, że jej elementy odpowiadają wierszom, a nie kolumnom danych. Przygotowanie tablicy na podstawie pliku tekstowego przebiega nieco inaczej. Listing 4 ilustruje różnicę. Natomiast szablon jest niemal identyczny. Różni się wyłącznie kolejnością indeksów <TD>{$tabela[nagrody][0]}</TD> oraz parametrem loop=$tabela.
Listing 4. Skrypt przekazujący do szablonu tablicę "poziomą". <?php $tabela = array(); $plik = file('nagrodynobla.txt'); $tmpcount = count($plik); for ($i = 0; $i < $tmpcount; $i++) { $linia = explode(':', trim($plik[$i])); } $tabela[] = $linia; $smarty = new Smarty; $smarty -> assign('tabela', $tabela); $smarty -> display('index.tpl');?> Tablica asocjacyjna Ostatni sposób przekazywania danych wielowymiarowych do szablonu stosuje tablice asocjacyjne. W tablicach takich indeksem elementu nie jest liczba całkowita, a napis. Wewnątrz pętli for widocznej na listingu 5, tworzona jest tablica asocjacyjna $tmp. W tablicy tej indeksami są napisy 'rok', 'fizyka', 'chemia' itd. Tablica $tmp jest dodawana jako ostatni element tablicy $nagrody. Listing 5. Skrypt smarty-ex-6-d przekazujący do szablonu tablicę wielowymiarową zawierającą tablice asocjacyjne. <?php $nagrody = array(); $plik = file('nagrodynobla.txt'); $tmpcount = count($plik); for ($i = 0; $i < $tmpcount; $i++) { $linia = explode(':', trim($plik[$i])); $tmp = array( 'rok' => $linia[0], 'fizyka' => $linia[1], 'chemia' => $linia[2], 'medycyna' => $linia[3], 'literatura' => $linia[4], 'pokojowa' => $linia[5] ); } $nagrody [] = $tmp; $smarty = new Smarty; $smarty -> assign('nagrody', $nagrody); $smarty -> display('index.tpl');?>
Sekcja iterująca tablicę $nagrody odwołuje się do pól stosując składnię <td>{$nagrody[nobel].fizyka}</td> Kompletna sekcja została przedstawiona na listingu 6. Listing 6. Szablon. {section name=nobel loop=$nagrody} <tr> <td>{$nagrody[nobel].rok}</td> <td>{$nagrody[nobel].fizyka}</td> <td>{$nagrody[nobel].chemia}</td> <td>{$nagrody[nobel].medycyna}</td> <td>{$nagrody[nobel].literatura}</td> <td>{$nagrody[nobel].pokojowa}</td> </tr> {/section} Przedstawione cztery metody przekazywania danych wielowymiarowych możemy stosować wymiennie w zależności od potrzeb. Przykład - Piosenki - jednopoziomowe menu Folder piosenki zawiera pliki tekstowe z tekstami piosenek dla dzieci. Zadanie polega na przygotowaniu strony prezentującej piosenki w postaci strony WWW. Strona ma posiadać menu składające się z tytułów piosenek. Wybór piosenki z menu ma powodować wyświetlenie jej treści obok menu. Stosując szablony musimy ustalić interfejs komunikacyjny skryptu z szablonem. Szablon musi otrzymać tekst wybranej piosenki oraz tablicę zawierającą tytuły wszystkich dostępnych piosenek. Po odczytaniu informacji z plików skrypt php przekaże do szablonu dwie zmienne $piosenki oraz $wybrana $smarty -> assign('piosenki', $smarty -> assign('wybrana', $piosenki); $wybrana); W samym szablonie znajdzie się jedna sekcja przetwarzająca tablicę $piosenki oraz instrukcja drukująca wartość zmiennej $wybrana. Hiperłącza umieszczane w spisie piosenek przekazują metodą GET do skryptu index.php zmienną id. Identyfikatorem piosenki jest jej indeks w tablicy. Jeśli piosenki pochodzą z bazy danych i ich identyfikatory są zapisane w bazie danych, wówczas tablica piosenki powinna być wielowymiarowa i zawierać oprócz tytułów również identyfikatory.
Listing 10. Szablon strony z jednopoziomowym menu. <table> <tr> <td> {section name=menu loop=$piosenki} <a href="index.php?id={$smarty.section.menu.index}"> {$piosenki[menu]}</a><br> {/section} </td> <td>{$wybrana nl2br}</td> </tr> </table> Funkcje if, ifelse oraz else Warunkowe przetwarzanie fragmentu szablonu Smarty realizujemy stosując funkcje if, ifelse oraz else. Dopuszczalne są trzy warianty składni powyższych funkcji. Pierwszy wariant jest najprostszy. Określamy warunek logiczny war. W przypadku, gdy warunek jest prawdziwy wówczas fragment szablonu fragment-szablonu jest przetwarzany, w przeciwnym razie fragment-szablonu zostanie pominięty {if war} fragment-szablonu {/if} Drugi wariant składniowy funkcji if zawiera opcjonalne wywołanie funkcji else. Jeśli warunek war jest spełniony to przetworzony zostanie pierwszy-fragment-szablonu. W przypadku, gdy warunek war jest fałszywy, przetwarzamy fragment drugi-fragment-szablonu {if war} pierwszy-fragment-szablonu {else} drugi-fragment-szablonu {/if} Ostatni możliwy wariant składniowy funkcji if zawiera wywołania funkcji elseif. Funkcję elseif możemy wywoływać wielokrotnie wewnątrz bloku ograniczonego wywołaniami {if} oraz {/if}. Pierwszy spośród warunków war1, war2, war3 oraz war4, który będzie spełniony, spowoduje wykonanie odpowiadającego mu fragmentu i zakończenie całej funkcji if. Wywołanie funkcji else jest oczywiście opcjonalne.
{if war1} pierwszy-fragment-szablonu {elseif war2} drugi-fragment-szablonu {elseif war3} trzeci-fragment-szablonu {else} czwarty-fragment-szablonu {/if} Warunek funkcji if oraz elseif Warunek logiczny będący parametrem funkcji if oraz elseif możemy zapisać stosując notację php. Warunek szablonu Smarty różni się od warunku języka php dwoma aspektami. w szablonie Smarty operatory porównania muszą być otoczone spacjami nie możemy użyć operatorów identyczności === i nieidentyczności!==. Wprawdzie autorzy systemu Smarty zdecydowali się na wzbogacenie repertuaru operatorów o te znane z języków shell systemów U*ix (np. ne, lt czy gt), to jednak wydaje się, że ograniczenie się do operatorów języka php ułatwi zarówno tworzenie jak i późniejsze usuwanie błędów czy analizę szablonów. Zatem jeśli zmienna {$naglowek} przekazana ze skryptu php ma sterować wyświetlaniem fragmentu szablonu (wartość równa 1 zmiennej mówi, że nagłówek ma być widoczny), wówczas należy użyć funkcji if w następujący sposób {if $naglowek == 1} szablon-naglowka {/if} Natomiast jeśli zmienna {$menuitem} decyduje o wyborze opcji menu, wówczas zawartość strony możemy uzyskać stosując szablon {if $menuitem == 0} szablon-artykulu {elseif $menuitem == 1} szablon-szablon-opisu {elseif $menuitem == 2} szablon-tutoriala {else} szablon-strony-glownej {/if} Przejdźmy do praktycznego wykorzystania funkcji if.
Menu strony i wybrany element Przygotujmy serwis prezentujący piosenki zespołu The Beatles. Płyta p.t. "Revolver" zawiera 14 utworów. Tytuły piosenek mają stanowić menu strony przedstawione na ilustracji 1. Po wybraniu tytułu piosenki z menu, na stronie powinien pojawić się tekst utworu. Tekst utworu wyświetlamy w tym samym miejscu, w którym znajdowało się menu. Wygląd strony po wybraniu piosenki p.t. "And Your Bird Can Sing" został przedstawiony na rysunku 2. Przygotowanie serwisu rozpoczynamy od organizacji zmiennych przekazywanych w kolejnych zapytaniach. W tym przypadku wystarczy pojedyncza zmienna. Nazwiemy ją id. Hiperłącza stosowane w aplikacji będą zatem miały postać <a href="index.php?id=5">...</a> Dane do serwisu stanowią pliki tekstowe i jeden obraz. Plik revolver.jpg przedstawia okładkę płyty, zaś plik revolver.txt zawiera listę piosenek zawartych na płycie. Trzy pierwsze linijki pliku revolver.txt są następujące Taxman 2:36 taxman.txt Eleanor Rigby 2:11 eleanor_rigby.txt I'm Only Sleeping 2:58 i_m_only_sleeping.txt... Każda linijka zawiera tytuł piosenki, czas trwania oraz nazwę pliku tekstowego, w którym jest zapisany tekst utworu. Zmienna id przekazywana w zapytaniu będzie wskazywała numer wybranej piosenki. Piosenki numerujemy od 0, dzięki temu numeracja będzie zgodna z indeksem danej piosenki w tablicy po wywołaniu funkcji file. Poprawnymi wartościami zmiennej id są liczby całkowite z przedziału od 0 do 13 włącznie. Po ustaleniu zmiennej id przekazywanej w zapytaniu oraz jej dopuszczalnych wartości ustalamy dane przekazywane ze skryptu php do szablonu. Danymi będą tablica zawierająca tytuły wszystkich piosenek (zmienna $revolver), informacja o tym, czy jakaś piosenka jest wybrana (zmienna $wybrany), numer wybranej piosenki (zmienna $numer), tekst wybranej piosenki (zmienna $tekst). Możemy przystąpić do zaprogramowania skryptu index.php. Najpierw ustalamy domyślne wartości zmiennych szablonu.
$wybrany = false; $tekst = ''; $numer = 0; Następnie wczytujemy zawartość pliku revolver.txt i kroimy kolejne linijki znakiem $revolver = file('dane/revolver.txt'); $liczba = count($revolver); for ($i = 0; $i < $liczba; $i++) { $linia = explode(' ', trim($revolver[$i])); $revolver[$i] = $linia; } Kolejny krok to weryfikacja wartości zmiennej id i ewentualne ustalenie wartości zmiennych szablonu $wybrany, $numer oraz $tekst if (isset($_get['id'])) { if (isvalidintegerfrom($_get['id'], 0, $liczba)) { $numer = $_GET['id']; $wybrany = true; $tekst = file_get_contents('dane/'. $revolver[$numer][2]); } } Wreszcie tworzymy obiekt Smarty i przekazujemy do niego cztery zmienne $smarty = new Smarty; $smarty -> assign('revolver', $revolver); $smarty -> assign('wybrany', $wybrany); $smarty -> assign('tekst', $tekst); $smarty -> assign('numer', $numer); $smarty -> display('index.tpl');