Mateusz matipl Kamiński: o programowaniu (m.in. PHP), Apple (iPhone, iPad), usługach Google i finansach

Zend Framework – obsługa wielu języków

Zend Framework Wstępnie chciałem napisać o lokalizacji, aby zaprezentować Wam jak można wykorzystać application.ini zamiast tworzyć własne zasoby (resource). Ale z drugiej strony może nie każdy wie jakie to proste w dzisiejszych czasach zrobić serwis wielojęzyczny z tłumaczeniem nie tylko statycznych napisów, ale również nawigacji czy lokalizacją kwot.

Do tłumaczeń korzystam z gettext (pliki .mo i .po). Moje pliki językowe znajdują się w project/languages i wygląda to tak:

matipl@host:~/project/languages$ ls
en_GB.mo  en_GB.po  pl_PL.mo  pl_PL.po

Gdy mamy stworzone własne tłumaczenia pora na skonfigurowanie zasobu translate w application.ini:

resources.translate.registry_key   = "Zend_Translate"
resources.translate.adapter        = "gettext"
resources.translate.content        = APPLICATION_PATH "/../languages/"
resources.translate.options.scan    = "filename"
resources.translate.disableNotices = false
resources.translate.options.logUntranslated = false
resources.translate.locale        = "pl_PL"

W ten oto sposób możemy już korzystać z plików lokalizacyjnych opartych o Zend_Translate (skonfigurowany zasób znajduje się w Zend_Registry::get(‘Zend_Translate’)). Niestety nie wie on z jakiej wersji językowej (pl czy en) chcemy skorzystać.

W tym celu stworzyłem plugin Zextend_Controller_Plugin_Locale, który pobiera wybrany (lub domyślny) język użytkownika i konfiguruje Zend_Translate. Dodatkowo mówimy widokowi i nawigacji, że ma się wspierać przez Zend_Translate z tym konkretnym językiem, który skonfigurowaliśmy.

class Zextend_Controller_Plugin_Locale extends Zend_Controller_Plugin_Abstract
{

    public function routeShutdown(Zend_Controller_Request_Abstract $request)
    {
        $view = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view');
        $locale = new Zend_Locale(Zextend_Lang::getActiveLang());
        Zend_Registry::set('Zend_Locale', $locale);

        $translate = Zend_Registry::get('Zend_Translate');
        $translate->setLocale($locale);

        $view->getHelper('translate')->setTranslator($translate);
        $view->navigation()->setTranslator($translate);

        Zend_Form::setDefaultTranslator($translate);

        Zend_Registry::set('Zend_Translate', $translate);

    }

}

Na koniec wystarczy włączyć nasz plugin w application.ini:

resources.frontController.plugins.locale = "Zextend_Controller_Plugin_Locale"

Teraz możemy już swobodnie korzystać z tłumaczeń na naszej stronie, np. w widoku wywołując:

<h2><?php echo $this->translate('Contact') ?></h2>

Dla słowa „Contact” musimy mieć oczywiście odpowiedni wpis w plikach *.po. Dla wersji PL:

msgid "Contact"
msgstr "Kontakt"

Po stworzeniu tłumaczenia pamiętajmy o wygenerowaniu pliku .mo komendą: msgfmt -o pl_PL.mo pl_PL.po.

Na koniec dodam, że w danych czasach sporo rzeczy robiłem poza application.ini. Chociażby przeciążałem zasób Db, aby wprowadzić SET NAMES UTF8, czy też w index.php wpisywało się dyrektywy PHP. A obecnie?

resources.db.adapter          =  "pdo_mysql"
resources.db.params.host      =  "db-1.project.pl"
resources.db.params.username  =  "project"
resource.db.params.password    = 'password'
resources.db.params.dbname    =  "project"
resources.db.isDefaultTableAdapter = true
resources.db.params.driver_options.1002 = "SET NAMES UTF8;"

phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0

Podobne wpisy:

CZYTAJ PRZEZ RSS

  • Mógłbyś jeszcze napisać btw. o tłumaczeniu routes. Łatwa a interesująca sprawa o której nie wszyscy wiedzą.

  • Napisałeś, że stworzyłeś specjalny plugin do wybierania języka dla użytkownika oraz na stałe konfigurujesz locale z poziomu application.ini.

    Wspominam o tym, bo z tego co mi wiadomo ZF potrafi sam wczytać odpowiednie translacje na bazie locale bądź useragena – tak przynajmniej wynika z dokumentacji, albo źle ją zrozumiałem. Próbowałeś w ten sposób? Ja w praktyce nie, dlatego pytam o ewentualne doświadczenia :)

  • @sokzzuka: dobra uwaga, jak znajdę chwilę to dopiszę/napiszę.

    @singles: bo auto-rozpoznawanie się nie sprawdza zawsze. Spójrz na 7. linię wtyczki:
    Zextend_Lang::getActiveLang()

    W widoku strony jest boks z wyborem wersji językowej.

  • Przydatne dla walidatorów:
    Zend_Validate_Abstract::setDefaultTranslator($translate)
    Pozdr.

Możesz śledzić odpowiedzi za pomocą kanału RSS 2.0