Wielojęzyczność w cakephp

statycznie

tworzymy pliki: /app/locale/eng/LC_MESSAGES/deafult.po

msgid  "new"
msgstr "New"

/app/locale/pol/LC_MESSAGES/deafult.po

msgid  "new"
msgstr "Nowy"

/app/locale/*lang_code*/LC_MESSAGES/deafult.po

msgid  "new"
msgstr "Pojakiemus nowy:)"

czyli:

  1. msgid - to identyfikator taki sam wszedzie
  2. msgstr - to tekst w danym jezyku

kody języków

Kody jezykow mozna znalezc tutaj.

szblony (VIEW)

Jeżeli chcemy wyswietlic tylko:

<li>__('new')</li>

Jeżeli chcemy zwroci do funkcji:

<li><?php echo $html->link(__('new',true), array('action'=>'add')); ?></li>

Jezeli funkcja nie znajdzie danego msgid w danym jezyku zostanie wyświetlony przekazany msgid. (W naszym wypadku “new” z małej litery)

zmiana języka

Configure::write('Config.language', 'pol');

odmiana

Cakephp wspiera odmiane rzeczowników w liczbie mnogiej (1 jabłko, 2 jabłka, 5 jabłek).

VIEW

Wcelu przetłumaczenia wyrazu na jego poprawna forme w liczbie mnogiej uzywamy fukcji "__n". Funckja ta przyjmuje 3 wymagane parametry [’forma_liczby_pojedynczej’,’forma_liczb mnogiej’,liczba_elementow]. 4 paramtr okresla czy funkcja ma wyswietlic ciag znakow czy zwrocic.

W ponizszym przykladzie jako liczbe pojedyncza podajemy “1 apple” a jako mnoga “%s apples”, ilosc elementow, oraz true aby funckja zrwocila wynik a nie wyswietlila go. Nastepnie gdy liczba jest inna niz 1 w zwroconym ciagu zamieniamy %s na liczbe elementow funkcja sprintf.


for($i=0;$i<120;$i++)
{
echo sprintf( __n('1 apple','%s apples',$i,true), $i); ?></h3>
} 

Aby wszystko działało dobrze porzeba nam jeszcze plik .po Ważna rzeczą jest aby pamiętać by w ‘Plural-Forms:’ podać odpowiednia regułę dla naszego języka

msgid ""
msgstr ""
"Project-Id-Version: CakePHP 1.2.x.x\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2007-04-21 03:28-0600\n"
"Last-Translator: Sławomir Wilusz <slawek (at) wilusz (dot) net>\n"
"Language-Team: devayd.com\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Poedit-Language: Polish\n"
"X-Poedit-Country: POLAND\n"
"X-Poedit-SourceCharset: utf-8\n"

msgid  "1 apple"
msgid_plural "%s apples"
msgstr[0] "1 jabłko"
msgstr[1] "%s jabłka"
msgstr[2] "%s jabłek"

w powyższym pliku możemy wyróżnić:

  • msgid - identyfikator dla liczby pojedynczej (podajemy go jako 1 paramtre w funckji __n)
  • msgid_plural - identyfikator dla liczby mnogiej (podajemy go jako 1 parametr w funckji __n)
  • msgstr[0] - tlumaczenie dla liczby pojednczej
  • msgstr[1] - tlumaczenie dla liczby mnogiej
  • msgstr[2] - 2 tlumaczenie dla liczby mnogiej

To która wersja zostaje zwrocona okresla nam reguła Plural-Forms.

liczba mnoga

przez osoby

TODO ?

dynamicznie

Obsluga wielojezycznosci w cake 1.2 realizowana jest poprzez behaviour “Translate”.

Aby z niego korzystac nalezy najpierw stworzyc tabele, ktorych struktura zawarta jest w pliku APP/config/sql/i18n.sql

nastepenie w modelu dodajemy linijkę


var $actsAs = array('Translate'=>array('field1','field2'));

Pola field1 i field2 nie muszą mieć kolumna w tabeli modelu. Pola te trzymane są dynamicznie w tabelach językowych.

Aby edytować pola filed1 field2 w szablonie dodajemy porostu

 echo $form->input("field1");  
 echo $form->input("field2");

Odczytywanie wykonuje sie następująco:


//odczyt rekordu o id 1 w jezyku polskim
$this->MODELNAME->locale= "pol";
$data = $this->MODELNAME->read(null,1);

Jeśli nie podamy ręcznie locale modelu, zostanie ustawione locale automatycznie przez cake lub z sesji (Config.language)

Zapisywanie:


//zapis rekordu  w jezyku polskim
$this->MODELNAME->locale= "pol";
$this->MODELNAME->save($this->data);

jeżeli chcemy by rekordy językowe byly ze soba powiazna (np artykul o id 1 ma rozne wersje jezykowe) nalezy po dodaniu (add) wykonac nastepujace funkcje:

Dla wersji wcześniejszych niż 1.2.0.5875 pre-beta:



$this->ModelName = MODELNAME;	
				$langs = $this->Language->findAllByActive(1);
				$i=0;
				$row_id = $this->{$this->ModelName}->getLastInsertID();
				
				
				foreach($langs as $lang)
				{
					if($this->Session->read('Config.language')!=$lang['Language']['code'])
					{
						$this->{$this->ModelName}->locale = $lang['Language']['code'];
						foreach($this->{$this->ModelName}->actsAs['Translate'] as $field)
						{
						$i++;
						$this->{$this->ModelName}->query("INSERT INTO `prefix__i18n_content` (`content`) VALUES ('') ");
					
						$insertID = 'insertID'.$i;
					
						$res = $this->{$this->ModelName}->query("SELECT LAST_INSERT_ID() AS $insertID");
					
						$i18n_content_id = $res[0][0][$insertID];		
				   		$this->{$this->ModelName}->query("INSERT INTO `prefix__i18n` (`locale`,`model`,`row_id`,`i18n_content_id`,`field`) VALUES ('".$lang['Language']['code']."','".$this->ModelName."',$row_id,$i18n_content_id,'$field')");
						}
					}
				}


Dla wersji 1.2.0.5875 pre-beta i poźniejszych:



	
				$langs = $this->Language->findAllByActive(1);
				$i=0;
				$row_id = $this->{$this->modelClass}->getLastInsertID();
				
				
				foreach($langs as $lang)
				{
					if($this->Session->read('Config.language')!=$lang['Language']['code'])
					{
						$this->{$this->modelClass}->locale = $lang['Language']['code'];
						foreach($this->{$this->modelClass}->actsAs['Translate'] as $field)
						{
						$i++;
				   		$this->{$this->modelClass}->query("INSERT INTO `prefix__i18n` (`locale`,`model`,`foreign_key`,`field`,`content`) VALUES ('".$lang['Language']['code']."','".$this->modelClass."','".$row_id."','".$field."','".$this->data[$lang['Language']['code']][$field]."')");
						}
					}
				}


powyzszy kod dodaje puste wartosc dla wszytkich pozostalych jezykow. Jezyki dla tego przykladu sa trzymane w tabeli languages i jest do nich zrobiony osobny model. Prefix jest reczenie ustawiony na “prefix”!

poEdit

Klika uwag które mogą zaoszczędzić Wam czasu podczas pracy z poEdit.

Program poEdit można ściągnąć tutaj

  1. File→Preferences→Pareser → wybrać np PHP → edit → dopisac roszerzenie “*.ctp;”
  2. File→New Catalogue (przykładowe dane dla projektu z polskim jezykiem)
    1. Project Info
      1. Project name: nazwa prjketu
      2. Team : nazaw zespolu tlumaczacego
      3. Team email - email zespolu tlumaczacego
      4. Language - Polish
      5. Country - Poland
      6. Charset - utf-8
      7. Source code - utf-8
      8. Plural Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10⇐4 && (n%100<10 || n%100>=20) ? 1 : 2;
    2. Paths
      1. Base path - /sciezka_do_cake/app/views (jesli tylko szablony)
      2. Paths - “comments” (bedzie szukalo w katalogu comments - sciezki sa wzgeldne wobec basepath)
      3. Paths - “../controllers” - wzgledne sciezki
    3. Keywords
      1. _ (standardowa funkcja ale jak podajemy keywords trzeba? ja podac od nowa)
      2. __ ( funkcja uzywana w cake’u)
      3. __n (funkcja w cake dla plurals)
      4. pozostałe których używaliśmy

Po takim skonfigurowaniu poEdit powinnie on wyswietlic komunikat ze rozszerzenie *.ctp jest nie znane i sprobuje uzyc *.c a nastepnie przeparsowac pliki i wyswietlic znalezione ciagi do przetlumaczenia.

Jeśli dodamy na końcu polecenia programu przetwarzającego (w preferencjach) –language=php, nie wyświetli on powyższego komunikatu.

UWAGA - poEdit nie rozpoznaje stringow objetych pojedynczymi cudzysłowami ' dlatego trzeba używać zawsze " ( __("tekst") zamiast __('tekst') )

UWAGA - cake najpierw sprawdza czy znajduje sie plik .mo i czasami zdarza sie ze choc w pliku .po sa juz nowe dane to cake ich nie widzi i najlatwiej wtedy usunac plik .mo sprawdzic czy jest ok i wygenerowac poprzez poEdit nowy plik .mo jesli jest ok (plik .mo generuje sie automatycznie podczas zapisu )

zewnetrzne linki


Personal Tools