2014-12-07

Localizing Zend Framework 2 application with PoEdit

Zend Framework 2 provides Internationalisation (I18N) support. In this post I will give you instructions how to configure Zend Framework 2 to work with translation of your ZF2-Modules using PoEdit step-by-step. It may seem like yet-another Zend Framework 2 and PoEdit instruction. I’m writing it, because I haven’t found any complex instruction from the beginning to the end, how to start with Internationalisation and configuration of localizing in Zend Framework 2.

Configure localizing in Zend Framework 2

In your Application module_config.php add alias to MvcTranslator:

'service_manager' => [
    'aliases' => [
        'translator' => 'MvcTranslator'
    ]
],

This step is not required but it helps you to manage of “translator” configure section in every module. 

Next, add “translator” configure section in your module_config.php:

'translator' => [
    'locale' => 'en_GB',
    'translation_file_patterns' => [
        [
            'type' => 'gettext',
            'base_dir' => __DIR__ . '/../language',
            'pattern' => '%s.mo'
        ]
    ]
],

Do not forget to create “language” directory in module. Your module’s directories should look like this:

/- module
|-/ NAMESPACE
|-/ config
|-/ language
|-/ src
|-/ view
|- Module.php
^

Download and configure PoEdit

First of all, you must download PoEdit from project site and install it. Next, open PoEdit and go to menu: File > Preferences > Extractors tab. Find PHP on list and edit it. Be sure that you have *.phtml in List of extensions, if not, add it.


How to create language files

In this step I will show you how to create *.po files. 
Open PoEdit and go to menu: File > New. 
Select language which you want to translate, example: English (United Kingdom)


Then press OK. After that, save your en_GB.po file (press save) in your module’s “language” directory. Next, you have to set up special properties for en_GB.po - go to menu: Catalogue > Properties. 
In “Translation properties” set up name project:


Open “Source paths” tab and set “Paths” like this:



“/path/MyApp/modules/MyModule” is the path to module in your application which you want to translate.
In “Sources keywords” tab add: translate



This keyword (translate) tells PoEdit that it should find all expressions in your module: translate; PoEdit finds every call of translate helper in your module. 
Press “Update”.


Then, in the “Source text” PoEdit will find and show every text to translate.

Use translate in Controllers

To add keywords to translate in your Controllers you can simply use:

$this->getServiceLocator()->get('translator')->translate('Text to translate');


Of course, it’s possible to translate texts in module class by passing translator object to them, but it’s strongly discouraged. You shouldn’t mix application and business logic.

Recognize of language client

In the end, you would like to set up selected language and translation to a user automatically, when user is visiting website. In Module.php simply add this:

$translator = $e->getApplication()
                ->getServiceManager()
                ->get('translator');

$translator
    ->setLocale(
        \Locale::acceptFromHttp(
            $_SERVER['HTTP_ACCEPT_LANGUAGE']
        )
    )
    ->setFallbackLocale('en_GB');

$_SERVER['HTTP_ACCEPT_LANGUAGE'] - gets the accepted languages from a browser. Module will be translated if application has the same *.po file as language sent by a browser . If not, “en_GB” will be set as a default language in setFallbackLocale('en_GB') method.

To use \Locale be sure that you have the intl-extension running. You must have

extension=php_intl.dll

enabled in your php.ini file.

In Module.php you can set your own methods to set language. It could be automatically set up as I showed you above or you can implement your own policy. It depends on your own preferences and needs.

2014-12-01

Lokalne repozytorium Composera

Composer szybko stał się standardem do zarządzania pakietami oraz ich zależnościami dla aplikacji PHP. Dzisiaj jest to podstawowe i niemal niezbędne narzędzie do pracy i rozwoju aplikacji. W tym wpisie chcę pokazać, jak w prosty i łatwy sposób utworzyć własny pakiet - repozytorium, by następnie pobrać go za pomocą Composera. 
Oczywiście, można użyć Satis lub Toran Proxy, aczkolwiek na własne potrzeby np. testów, wystarczy prostsze rozwiązanie, które opisuje w dalszej części posta.

Repozytorium Composera możemy utworzyć we własnej sieci np. na tym samym komputerze, na którym rozwijamy główny projekt, a następnie pobierać go przez Composera, bez publikowania go na GitHUB.

Czasem może zdarzyć się taka sytuacja, kiedy nie chcemy publikować naszego pakietu i umieszczać go publicznie na GitHUB. Może to być sytuacja w której, dopiero zaczynamy pracować nad własnym pakietem, nasz pakiet może być specyficzny tylko dla naszej aplikacji i nie nadaje się dla innych aplikacji, jak również może to być rozwiązanie zamknięte rozwijane na potrzeby projektu komercyjnego.

W tym wpisie nie będę opisywał podstaw Composera. Można z nimi się zapoznać w oficjalnej dokumentacji.


Zaczynamy!

Na początku utworzymy nowy projekt. Jego struktura będzie wyglądała następująco:


main-project-directory
|-src
| \-module
|   \-Start.php
|-examples
\-test


Utwórzmy powyższą strukturę katalogów, a następnie zainicjujmy repozytorium git:


cd main-project-directory
git init
git add .
git commit -m "Pierwszy commit"


Już mamy utworzony projekt. Teraz możemy przystąpić do konfiguracji Composera w naszym projekcie. W tym celu tworzymy plik composer.json w głównym katalogu projektu, a następnie definiujemy konfigurację:


{
 "name": "my-projects/my-module",
 "description": "Description of my project",
 "type": "library",
 "license": "BSD",
 "keywords": [
   “keywords"
 ],
 "authors": [
   {
     "name": "Name Surname",
     "email": "email@email.com"
   }
 ],
 "version": "dev-master",
 "require": {
 },
 "autoload": {
   "psr-0": {
     "MyModule\\": "src/"
   }
 }
}


Z kolei w pliku composer.json projektu, do którego chcemy zaciągnąć nasz wcześniej utworzony moduł, musimy dodać wpis z repozytorium, z którego należy pobrać moduł:


{
   "name": "my_projects/main_project",
   "repositories": [{
       "type": "vcs",
        "url": "/path_to_module/my_module"
       }
   ],
   "require": {
       "my-projects/my-module" : "dev-master"
   }
}


Wartość dla “url” w sekcji "repositories" może być ścieżką na komputerze lokalnym albo adresem URL do którego jest dostęp w sieci.

Teraz wystarczy wydać polecenie > composer update, by pobrać do naszego miejsca docelowego utworzone wcześniej repozytorium.
Podczas konfiguracji composer.json w projekcie, do którego będzie zaciągane repozytorium, należy zwrócić szczególną uwagę na poprawność ścieżek - wielkość znaków ma znaczenie.