Dnes popíši několik zkušeností, které jsem nasbíral při pokusu alespoň částečně
lokalizovat své stránky. Bude se to týkat hlavně modulu Zend_Translate.
První věc, kterou je potřeba zmínit je, že Zend_Translate nám slouží k lokalizaci
jen určitých čáští aplikace - statických textů - zejména jde o nadpisy, menu, hlášky apod.
Takové texty
jsou většinou součástí designu, v případě Zend_Frameworku jsou tedy ve view šablonách.
Zend_Translate nám nepomůže s lokalizací obsahu aplikace, např. s texty článků
pokud píšeme nějaké CMS, s popisy zboží pokud děláme e-shop atd. V tom
si musíme pomoci sami viz třeba článek
Jakuba Vrány.
Stávající PHP nabízí jedinou možnost a to gettext. Samozřejmě si to také můžeme řešit sámi přes nějaké pole apod. Gettext je můžné klidně použít i se Zend_Frameworkem, nicméně musíte si dát pozor na to, že gettext sám o sobě a tím pádem ani gettext PHP extenze není thread safe a nemůžete ho použít v multithreaded prostředích (zejména asi IIS, Apache jsem v reálu používat jako multithreaded ještě neviděl).
V čem tedy spočívá práce Zend_Translate? Jedná se o třídu, které podhodíte nějaký řetezec, který chcete přeložit, ona si prostřednictvím adaptéru najde v nějakém externím zdroji jeho překlad a vrátí vám ho, pokud překlad nenajde vrátí ten samý řetězec, co jste jí poslali. Adaptérů je vícero, od obyčejného PHP pole, přes gettext,cvs až po XML a připravuje se i SQL. Osobně jsem používal jen gettext, protože má dobrou podporu externích nástrojů pro práci s překlady a je díky kompaktnímu binárnímu formátu i rychlý. Je nutné poznamenat, že Zend_Translate pracuje s binárními gettext soubory bez použití php gettext rozšíření. Gettext doporučují i i v referenčním manuálu.
Pro použití Zend_Translate lze postupoval takto:
- Zaintegrovat inicializaci Zend_Translate do bootstapu, případně controller pluginu.
- Napsat si View Helper, hlášky jsou většinou všechny ve view šablonách.
- Přepsat některé hlášky v šablonách na volání helperu.
- Pomocí externích utilit proscanovat view šablony a vyrobit překlady.
- Otestovat.
- Dopřeložit zbytek.
Zend_Translate je dobré si v bootstrapu inicializovat překladem daného jazyka, například podle toho, jaký jazyk si uživatel vybral atd. Stejně tak můžeme použít plugin controller. Název zvoleného jazyka můžeme s výhodou použít pro vybrání souboru s překladem. Objekt si pak pro pozdější použití uložíme do Zend_Registry.
//somewhere in bootstrap index.php
$lang="cs";
$translator=new Zend_Translate("gettext","/app languages/messages.{$lang}.mo",$lang);
Zend_Registry::set("translator",$translator);
Pak si napíšeme view helper, například takto:
<?php
class MyApp_View_Helper_Trans
{
/**
* translator
* @var Zend_Tranlate
*/
private $_translator;
//======================================================
/**
* Sets the translator from the registry.
*/
public function __construct()
{
$this->_translator=Zend_Registry::get("translator");
}
//======================================================
/**
* Main helper function.
* Returns translation for a given string.
* @var string $str string for a translation
* @return string
*/
public function trans($str)
{
return $this->_translator->_($str);
}
#END CLASS
}
Přepínání jazyků můžeme zajistit nějakou controller akcí. Zend_Translate samozřejmě metody na přepínání jazyků poskytuje.
Někde ve view skriptu pak budeme pracovat s překládaným textem takto:
<h2><?php echo $this->trans("Description")?></h2>
<p>What is it? Some useless description.</p>
Adresář pro překlady - languages
jsem umístil dle doporučení
referenčního manuálu takto:
app languages lib modules blog controllers models views default controllers
Teď příjde na řadu projít naše zdrojové kódy a vytahat z nich řetězce, které
chceme přeložit. S gettextem do jde poměrně dobře, mě stačil tento shell skriptík,
který spouštím z adresáře ../app
přes makefile.
Skipt projde zdrojové kódy, vytahá z nich argumenty funkce trans
a zaktualizuje soubory s překlady
(.po - Portable Object) a nakonec z nich vytvoří binární soubory (.mo - Machine Object).
Bohužel nelze použít keyword $this->trans
, scanovací program
xgettext
pak nic nenajde.
$ cat app/languages/gettextUtils.sh
#!/bin/sh
mainDir=../../app/
langDir=$mainDir/languages
messagesFile=$langDir/messages.pot
messagesCS=$langDir/messages.cs.po
messagesCSMO=$langDir/messages.cs.mo
messagesEN=$langDir/messages.en.po
messagesENMO=$langDir/messages.en.mo
sourceDir=$mainDir
> $messagesFile
for file in `find $sourceDir -type f \( -name *.phtml -o -name *.php \) -print`; do
echo "scannig $file"
xgettext -j --keyword=trans --from-code=ascii \
--default-domain=messages --language=php \
--output=$messagesFile \
$file
done
echo "updating CS PO"
msgmerge -U $messagesCS $messagesFile
echo "updating EN PO"
msgmerge -U $messagesEN $messagesFile
echo "formating CS MO"
msgfmt $messagesCS -o $messagesCSMO
echo "formating EN MO"
msgfmt $messagesEN -o $messagesENMO
rm -f $langDir/*~
Soubory s překlady upravuji normálně v textovém editoru, s překlady je potřeba pracovat v utf-8, Zend_Translate s tím počítá.
Interně Zend_Translate pracuje tak, že si všechny překlady natáhne po inicializaci přes daný adaptér do paměti a pak překlady prohledává v paměti, na soubor s překladem už nesahá. Podporováno je i více jakyků zárověn, ačkoli to asi moc lidí nevyužije.
Potřebu view helperu si uvědimili i sami autoři Zend_Frameworku a vznikl návrh na
Zend_View_Helper_Translate.
Zajímavé na něm je, že má poskytovat metodu "podtržítko". Ve view se bude moci používat stylem
podpobným jako metoda
Zend_Translate::_()
, tedy $this->_("Some string")
. Jen jsem dost zvědav, jak se bude ve view inicializovat. Kvůli jmenné konvenci
a umístění helperů si to teď dost dobře nedokážu představit. Podle mě budou muset nějak ohnout samotný view objekt.
Komentáře (0)
Komentáře jsou uzavřeny.