Gettext w systemie szablonów Smarty.
Smarty to system szablonów dla php o którym można się trochę dowiedzieć z polskiego wiki. System szablonów to przede wszystkim rozdzielenie warstwy prezentacji strony www (kod html) od kodu logiki strony (kod php).
Gdy pokazywałem podstawy współpracy Gettext z php, wszystkie wywołania html były generowane z poziomu skryptu php – dobrze sprawdza się to przy bardzo małych i ubogich w treść, podstronach www, lecz jest niedopuszczalne jeśli mamy stworzyć bardzo rozbudowaną podstronę z dużą ilością generowanych informacji.
Smarty to nie tylko rozdzielenie zadania prezentacji dynamicznej strony www na te dwie warstwy (bo do tego tak naprawdę nie potrzebujemy Smarty i można to zrobić samemu) lecz bardzo rozbudowane i uproszczone tworzenie warstwy prezentacji (html) przez stosowanie bardzo wielu funkcjonalności w kodzie szablonu *.tpl (pętle do przeglądania tablic, funkcje manipulujące na tekście i jego właściwościach, konfiguracja w plikach, włączanie innych plików a nawet możliwość włączenia kodu php czego bardzo nie polecam).
Ściągając najnowszą wersję Smarty’ego, znajdziemy tam bardzo dobry przykład (demo_smarty) pokazujący jego podstawowe możliwości, więc nie będę tutaj tego powtarzał ( w celu jego odpalenia konieczna może być zmiana ścieżki require(’smarty/libs/Smarty.class.php’);
Instalacja Smarty’ego to tak naprawdę rozpakowanie archiwum i umieszczenie go w dostępnej dla skryptu lokalizacji. Najważniejszy jest podkatalog libs/, który zawiera klasy szablonu. Ponieważ Smarty’ego będziemy wykorzystywać w wielu projektach, warto żeby katalog gdzie go rozpakowaliśmy dodać do zmiennej include_path z pliku php.ini.
Ponieważ nie jest to w moim stylu, utworzyłem podkatalog smarty\ w katalogu instalacji PEAR’a:
G:\Program Files\PHP\PEAR\smarty\ (dla Windows)
/usr/share/php/smarty (dla Debiana)
i tam przekopiowałem cały katalog libs\ z rozpakowanego archiwum Smarty’ego. Jest więc on dostępny tak, jak reszta bibliotek PEAR, czyli np.
require_once('smarty/libs/Smarty.class.php');
Poniżej znajduje się trochę bardziej rozbudowany przykład , który został wcześniej podany dla pokazania współpracy php z gettext, a rozszerzony właśnie o system szablonów Smarty.
<?php require_once('smarty/libs/Smarty.class.php'); $smarty = new Smarty; $smarty->compile_check = true; //$smarty->debugging = true; $language_code = 'pl_PL'; putenv("LANG=$language_code"); setlocale(LC_ALL, $language_code); $domain = 'wiadomosci'; bindtextdomain($domain, getcwd()."/locale"); bind_textdomain_codeset($domain, 'utf-8'); textdomain($domain); $smarty->assign("language_code",$language_code); $smarty->assign("files",array('ss','ssss')); $smarty->display('index.tpl'); ?>
Do nowości zaliczyć można tylko i wyłącznie stworzenie obiektu Smarty i wywołania paru jego metod. Jest to bardzo intuicyjne, jeśli podam jak wygląda plik szablonu w języku html, który jest użyty przez powyższy kod (plik index.tpl):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Smarty with gettext</title> </head> <body> <h1>Wybrane ustawienie jezykowe: {$language_code}</h1> {t}A message to translate{/t} <br /> {t}message2{/t}<br /> <PRE> {t 1=$files|@count} We have %1 {/t}{t count=$files|@count 1=$files|@count plural="%1 files"}File{/t} {t}in current dir.{/t} {t escape=no url="http://www.php.net/" name="PHP website"} <a href="%1">%2</a> {/t} {t url="http://www.php.net/" name="PHP website"} <a href="%1">%2</a> {/t} </PRE> </body> </html>
Smarty narzuca pewną konwencję w stosunku do przechowywania plików szablonów (*.tpl). Domyślnie pliki te powinny być umieszczane w podkatalogu /templates/, dodatkowo stworzony musi być podkatalog /templates_c/ (z prawami do zapisu w Debian’ie) gdzie zapisywane są skompilowane szablony do kodu php. Oczywiście możemy to zmienić, zmieniając podane niżej wartości domyślne:
$smarty->template_dir = './templates/'; $smarty->compile_dir = './templates_c/';
Dla uporządkowania informacji, podam w jaki sposób są rozmieszczone pliki dla domyślnej konfiguracji( z której ja również korzystam):
\index.php
\templates\index.tpl
\templates_c\ (pusty do pierwszego wywołania skryptu na stronie www.
Sam plik index.tpl który przedstawiłem wyżej nie jest taki standardowy jak można by założyć – zawiera on bowiem znaczniki {t} i {/t} które domyślnie nie są w Smarty dostępne. Stają się dostępne po ściągnięciu rozszerzenia dla Smarty’ego o nazwie smarty-gettext.
To rozszerzenie służy nam do osadzania tekstów, które mają podlegać tłumaczeniu. Jak można zauważyć, wszystkie teksty które były tłumaczone przez gettext() jako funkcje php w skrypcie, teraz zamknięte są w znacznikach {t} {/t}. Tak bowiem dzięki temu rozszerzeniu można używać gettext’a w plikach szablonów *.tpl.
Żeby zainstalować to rozszerzenie, musimy skopiować plik block.t.php ze ściągniętego archiwum i rozpakować do katalogu plugins\ w Smarty (G:\Program Files\PHP\PEAR\smarty\libs\plugins\block.t.php). Drugi z plików php z archiwum: tsmarty2c.php kopiujemy do katalogu roboczego naszej strony www (w którym znajduje się stworzony wyżej plik *.php).
Bardziej zaawansowana część dotycząca użycia gettext w Smarty znajduje się pomiędzy znakami <PRE></PRE>.
Pierwsza z nich:
{t 1=$files|@count} We have %1 {/t}{t count=$files|@count 1=$files|@count plural="%1 files"}File{/t} {t}in current dir.{/t}
spowoduje obliczenie ilości elementów tablicy w zmiennej $files a następnie wypisania przetłumaczonego tekstu w 3 etapach:
- przetłumaczonego fragmentu “We have %1“,
- odmienionego słówka “File” w zależności od otrzymanej liczby elementów tablicy $files,
- przetłumaczonego fragmentu “in current dir“.
Następne linie pokazują sposób, w jaki należy przekazywać adresy www. W pierwszy podejściu używane jest słowo kluczowe “escape=no”, co powoduje nie escape’owania znaków html w tym wywołaniu, ponieważ domyślnie wszystkie one są escape’owane ze względu na bezpieczeństwo.
Pokazuje to drugi przykład z adresem strony www, który zostaje zamieniony na postać tekstu, a nie znaczników html.
Z poprzednich wpisów wiemy też, jak parsować pliki w poszukiwaniu tekstów podlegających tłumaczeniu. Niestety nie zadziała ona dla takiego skryptu *.tpl z racji użycia innych słów kluczowych oraz sposobu interpretacji tekstu.
Rozwiązania nie trzeba wcale daleko szukać, ponieważ jest ono dostarczone z rozszerzeniem, które ściągliśmy do Smarty’ego i nazywa się tsmarty2c.php oraz zostało wcześniej skopiowane do katalogu roboczego ze stroną www.
Służy on do wygenerowania pliku pośredniego, który już może zostać użyty przez parser gettext’a.
Uruchamiamy więc w katalogu z plikiem tsmarty2c.php polecenie:
php -q tsmarty2c.php templates/index.tpl > texts.c
co spowoduje utworzenie pliku texts.c, o zawartości którą można już sparsować i dodać do pliku widomosci.po poleceniem:
xgettext -o wiadomosci.po –join-existing –omit-header –no-location texts.c
Ostatecznie wygenerowanie nowego pliku *.mo to wydanie polecenia:
msgfmt -o smartybook.mo smartybook.po
Należy go zaktualizować w katalogu locale/ dla języka pl_PL, zrestartować serwer apache’a i odpalić stronę w przeglądarce.
W efekcie powinniśmy uzyskać taką zawartość strony www:

Konfiguracja (Debian):
Apache/2.2.9 (Debian) PHP/5.2.6-0.1~lenny1 with Suhosin-Patch Server,
Processor : AMD Athlon(tm) XP 3000+,
Memory : 1296MB,
Operating System : Debian GNU/Linux 5.0,
Pakiet: gettext, Wersja: 0.17-4
Biblioteka: Smarty-2.6.20
Konfiguracja (Windows):
Apache/2.2.10 (win32) PHP/5.2.6,
Processor : AMD Athlon(tm) XP 3000+,
Memory : 1296MB,
Operating System : Windows XP 32 bit SP3,
Biblioteka: gettext, Wersja: 0.13.1 woe32.
Biblioteka: Smarty-2.6.20.
Brak komentarzy.