Zenedith's dev blog

Dałem się namówić.., szatanowi chyba..

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:

  1. przetłumaczonego fragmentu “We have %1“,
  2. odmienionego słówka “File” w zależności od otrzymanej liczby elementów tablicy $files,
  3. 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:

smarty_html

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.

2 styczeń, 2009 - Opublikował/a zenedith | web | , | Nie ma jeszcze komentarzy

Brak komentarzy.

Dodaj komentarz