Wiele języków na stronie

Za języki na stronie odpowiedzialna jest klasa i18n. Implementacja języków jest stosunkowo łatwa. Standardowo zalecam pisanie komunikatów w języku angielskim i umieszczanie tłumaczeń na inny język w pliku językowym. Używanie różnych języków nie jest zbyt skomplikowane, trzeba jednak pamiętać o tym, aby komunikaty do przetłumaczenia – czy to w widokach, czy kontrolerach (np. wyciągnięte z bazy) – umieszczać w specjalnym znaczniku.

Aby używać różnych języków, należy wszystkie komunikaty, które mają być przetłumaczone umieszczać w znaczniku:

__('To translate');

Przetłumaczony komunikat należy umieścić w pliku w folderze /application/i18n/
Plik powinien mieć nazwę taką jak nazwa języka. Np. dla polskich komunikatów: pl.php
Wzór jaką powinien mieć strukturę znajduje się poniżej.
/application/i18n/pl.php

<?php defined('SYSPATH') or die('No direct script access.');

return array(
    //'To translate'=>'Tłumaczenie na dany język',
    'Incorrect login or password.'=>'Nieprawidłowy login bądź hasło',
    'Fill the fields'=>'Uzupełnij pola',
    'Login'=>'Logowanie',
    'Password'=>'Hasło',
    );
?>

Później odpowiednie czynności spowodują, przetłumaczenie wszystkich komunikatów znajdujących się w __(”) na dany język. Jeśli komunikat się powtórzy, zostanie zmieniony wszędzie tam, gdzie wystąpił.

echo __('Login');

po zmianie na język pl będzie się równało z tym, jakbyśmy wpisali

echo 'Logowanie';

Gdy mamy gotowy plik językowy pl.php, czas zająć się kodem, który spowoduje przełączanie języków i pamiętanie języka w cookie.
1. W pliku /application/config/lang.php umieszczamy listę dostępnych języków. Plik ten będzie zawierał tablicę z językami, a w momencie odwołania się do niego, zwróci nam dostępne języki.

<?php defined('SYSPATH') or die('No direct script access.');

return array(
    'en-us' => 'English',
    'pl-pl' => 'Polski',
);

2. Kontroler odpowiedzialny za zmianę języka ma następującą strukturę:
/application/classes/controller/lang.php

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Lang extends Controller {

    public function before() {
        parent::before();
        $lang = $this->request->action();
        I18n::lang($lang);
        setcookie("lang", $lang,31536000 + time(),'/');
        $this->request->redirect();
    }

    public function action_index(){

    }
}
?>

W before() tego kontrolera pobierany jest język z linku z miejsca gdzie standardowo jest nazwa akcji. Więc z linku /kohana/lang/pl-pl zmienna $lang przyjmuje wartość ‚pl-pl’.

$lang = $this->request->action();

Ustawiany jest język z linku

I18n::lang($lang);

Zapisywany jest także do cookie, aby po ponownym wejściu na stronę ustawiono wcześniej wybrany język

setcookie("lang", $lang,31536000 + time(),'/');

Nazwa cookie: ‚lang’, wartość ze zmiennej $lang, czas życia w sekundach (31536000 = 60*60*24*365, a więc na rok), od chwili obecnej: +time(), dla strony głównej: ‚/’

Następuje przekierowanie na stronę główną

$this->request->redirect();

3. Kod ustawiający język z cookie umieśćmy w konstruktorze klasy z szablonem. Jeśli bazujemy na plikach z tego bloga, umieszczamy go w konstruktorze Default w pliku
/application/classes/controller/default.php

public function  __construct(Request $request, Response $response) {
        parent::__construct($request, $response);

        if(isset($_COOKIE['lang'])){
            setcookie("lang", $_COOKIE['lang'],31536000 + time(),'/');
            I18n::lang($_COOKIE['lang']);
        }
    }

Kod ten sprawdza czy w cookies jest zmienna lang. Jeśli jest to dla tego języka przedłuża ‚czas życia’ ciasteczka. Następnie przełącza na język w nim ustawiony.

4. Na stronie głównej wyświetlamy dostępne języki. Jeśli korzystamy z szablonu z tego bloga, w konstruktorze default w akcji index() wczytujemy do zmiennej content widok home, przesyłamy do widoku dostępne języki z configu lang.php
/application/classes/controller/default.php

public function action_index() {
$this->template->content='home';
$this->template->langs=Kohana::config('lang');
}

5. W widoku home tworzymy linki dla języków.
/application/views/home.php

<?php foreach($langs as $key => $lang){
    echo '<a href="lang/'.$key.'">'.$lang.'</a> ';
}?>

To wszystko. Prawda, że proste?

* Umieszczając w __() zmienną zawierającą string, sprawiamy, że w zależności co zostanie do niej przypisane, zostanie przetłumaczony odpowiedni komunikat.

$ditigs=array('one','two');
$digit=$digits[1]; //$digits[0];
echo __($digit);

W pliku językowym dodajemy:

'one'=>'jeden',
'two'=>'dwa',

W zależności jaką wartość przyjmie zmienna $digit (one, two), na stronie zostanie przetłumaczony odpowiedni komunikat. Można to wykorzystać do tłumaczenia komunikatów umieszczonych w bazie, bądź atrybutów obiektu.

Tłumaczyć można również komunikaty validacji, ale to pokażę w innym wpisie.

12 Odpowiedzi :“Wiele języków na stronie”

  1. Destrix napisał:

    Przyda się :)

  2. W ramach bezczelnej samopromocji wspomnę tylko, że swego czasu popełniłem podobny, chociaż nieco bardziej rozbudowany wpis w którym opisuję zalety i wady kilku rozwiązań i wskazuję moim zdaniem najlepsze.

  3. Rafau napisał:

    hmm.. zrobione wg tego co napisane i dostaje
    Call to undefined method Kohana::config()

    • Mariusz napisał:

      Wpis był dodany przed KO3.2, a od tej wersji zmieniło się odwołanie do cknfigów. Musisz to zamienić na:

      Kohana::$config->load('lang');
      

      Była o tym mowa we wpisie o mapach google, albo polecam przeczytanie wpisu o wydaniu wersji 3.2, bo zrezygnowano taż z odwołania do parametrów bezpośrednio z akcji.

  4. Kamil napisał:

    Witam niestety mam problem chciałem zrobić trochę inne tłumaczenie z polskiego na angielski a więc plik pl.pl zmieniłem na en.php zapisałem w funkcji

    __('Witaj na stronie głównej')
    

    a w pliku en.php odpowiednie tłumaczenie. Niestety nie chce tłumaczyć. Czy to wina polskich znaków? Da się coś z tym zrobić? Kiedy daje np.

    __('Hello')
    

    jako polski to mi dobrze tłumaczy.

    • Mariusz napisał:

      W bootstrap.php definiuje się defaultowy język, spróbuj zmienić tam na pl i daj znać czy działa.

  5. Kamil napisał:

    nic to nie dało. Chyba jednak polskie znaki nie lubią się z kohaną ;)

    • Mariusz napisał:

      W funkcji __() trzeci parametr to język, jeśli nie podasz to będzie en-us. Albo wszędzie dodać:

      __('Witaj na stronie głównej', NULL, 'pl-pl')
      

      Albo zmień w klasie I18n w funkcji __() trzeci parametr na pl-pl, tylko nie w katalogu /system, tylko skopiuj:
      /system/classes/kohana/i18n.php
      do
      /application/classes/kohana/i18n.php
      i wtedy zmień.

    • Kamil napisał:

      a jeszcze jedno pytanie jak tłumaczyć teksty z foldery messages gdzie przechowuje teksty do walidacji?

    • Mariusz napisał:

      Teksty z messages powinny się tłumaczyć automatycznie. Wystarczy mieć odpowiednie tłumaczenia z messages w pliku językowym i wysłać błędy po ich wystąpieniu.
      Teksy do reguł walidacji Kohany są w /sysetm/messages/validation.php
      Należałoby je przetłumaczyć (są np. w archiwum z drugie starcie) i ewentualnie dodać własne reguły o ile jest taka potrzeba.

      Używanie dodatkowych reguł przedstawia się tak:
      Np. w modelu Entry mamy funkcję sprawdzającą unikalny tytuł.
      W kontrolerze dodajemy regułę tego modelu (zwraca FALSE jeśli jest unikalny lub TRUE jeśli nie)

      ->rules('title', array(array('not_empty'), array('Model_Entry::unique_title') ))
      

      W messages mamy tablicę:

      'Model_Entry::unique_title'=> 'Title must be unique',
      

      a w pliku tłumaczącym (tu akurat z en => pl)

      'Title must be unique'=> 'Tytuł musi być unikalny',
      

Dodaj komentarz

Dodając kod PHP używaj tagów: [php][/php]

*