Gettext na 100% v šablonách

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
h4kuna
Backer | 740
+
0
-

Aktuálnější dokumentace na githubu

Zdravím,

hrál jsem si překlady a taky jsem došel k gettext translatoru všiml jsem si že využívá gettext z minima vlasně vůbec jen binarni soubor který naparsuje a pak z něj udělá pole. Na jednu stranu je výhoda v tom že když jsem rozjížděl gettext tak jsem pravděpodobně zestárnul a toto to naprosto obchází takže jsem to zachoval ve svém kódu, Roman Sklenář to nemá na gitu, tak je to u mě.

Potřebujete:

  • mít zapnutý gettext
  • mít nainstalovanou podporu jazyka na servru $ locale -a
  • všechno mít v UTF-8 (což 99,99% z vás bude mít)
  • soubory ke stažení
  • poedit

Pokud se nepodaří něco zajistit nezoufejte ještě je naděje, rozepíšu úplně dole.

Na gitu je ukázkový config.neon

definice jazyků, které chcete viz $ locale -a

parameters:
    langs: {'cs' : 'cs_CZ.utf8', 'en' : 'en_US.utf8'}

Přetížení makra {_' ‚} a přidání dalšího, pro množné číslo {_n‘ '}

factories:
    nette.latte:
        factory: \h4kuna\GettextLatte::latte

Registrace samotného překladače

services:
    translator:
        class: \h4kuna\GettextLatte(%appDir%/../locale/, %langs%)

Soubory jsou uloženy v adresáři locale, kde musíte dodrže další adresářovou strukturu. Stejná adresářová struktura je také na githubu.

locale (volitelný název)
    + cs
        + LC_MESSAGES
            + messages.mo
    + jiný jazyk (klíč z pole %langs%)
        + LC_MESSAGES (adresář definovaný phpkem)
            + váš binární soubor messages.mo (název lze změnit, je to 4. parametr @translator)

Adresáře LC_MESSAGE vyžadují práva 777 bug

V tom nejhlavnějším startupu je potřeba spustit servisu a dát ji parametrem jazyk, pokud ho máte jako persistentní v presenteru, tak asi takto.

<?php
$this->context->translator->setLanguage($this->lang);
// Zase musí odpovídat jednomu z klíčů v poli %langs%.
?>

Mimo šablony používáte gettext tzn:

<?php
echo gettext('Hi'); //nebo alias _
echo _('Hi');
echo ngettext('dog', 'dogs', 2);
echo $this->context->translator->translate(gettext('%s possible %s %s'), 'dalsi', 'volitelne', 'parametry');
?>

Aplikaci by jste měli psát v angličtině/němčině, aby šlo dobře definovat skloňování. Pokud budete psát aplikaci v češtině, tak počítejte s tím že si budete muset udržovat slovník z češtiny do češtiny, ale stačí jen u frází, kde je potřeba skloňovat, já to tak dělám.

A v šablonách první parametry dělají to samé co originální funkce gettextu, ale tím to nekončí. Budu požívat vykřičníky, ale jde to i bez nich a určitě je vyhoďte pokud text bude od uživatele. Všechny řetězce pro nahrazení požívejte %s.

{!_'Hi'}

překlad

echo gettext('Hi');

nic zajmavýho, ale toto je killer

{!_'Today is %s', $date}

překlad

echo sprintf(gettext('Today is %s'), $date);

Počet parametů není omezený to samé je pro množné číslo, podpora plurálu je vyřešená.

{!_n'%s dog', $count}

překlad

echo sprintf(ngettext('%s dog', '%s dog', $count), $count);
{!_n'dog', $count}

překlad

echo ngettext('dog', 'dog', $count);

Pokud se v proměnné nachází abs příklad $absCount vygeneruje

echo sprintf(ngettext('%s dog', '%s dogs', abs($absCount)), $absCount); // když bude potřeba skloňovat i záporné hodnoty (°C)

sprintf se doplňuje pokud je opravdu potřeba. Konec nesmyslných helperů a nemusíte používat ITranslator ikdyž to mám implementované, ale opravdu není potřeba ho registrovat do formulářů nebo šablon. Skloňování se v šablonách nepíše, to si úkládejte vždy do slovníku, pak jej nebudete muset kopírovat.

Celé k nahlédnutí a ke stažení

Na gitu je adresář locale a v něm dva prázdné slovníky (*.po) připravené pro češtinu a angličtinu včetně správné adresářové struktury.

Než začnete prohledávát poeditem je potřeba mít vygenerované všechny šablony ukázka jak toho docílit je v ukázkové presenteru zkopírujte, upravte namespace a je potřeba docílit spuštění actionTranslate.
Poeditem pak necháte prohledat adresáře temp/cache/_Nette.FileTemplateapp

Restart serveru po aktualizaci katalogu není potřeba.


Nesplněné podmínky

Není podpora gettextu nainstalovaná

  • nemělo by vadit je naimplementovaná podpora (testováno)

Nemohu zapnout požadovaný jazyk, server nevlastním.

  • 3. parametr @translator nastavte na TRUE a pak je potřeba zaregistrovat si translator do formulářů
  • tento stav silně nedoporučuji

Windows nepodporuje setlocale()

  • ano, je to na to připravené (testováno)

Nemám UTF-8

  • smůla nebo sáhnout do zdrojáku a upravit GettextLatte.php + katalogy

S chutí do toho.

Editoval h4kuna (14. 3. 2013 9:51)

redhead
Člen | 1313
+
0
-

Hezké!

pekelnik
Člen | 462
+
0
-

@h4kuna mas to pekne zpracovany :) o tom zadna…

Ja gettext nepouzivam. Vadi mi na nem 2 veci:

  • poedit
  • nutnost psat plural vsude kde ho chci pouzit – s preklady je prace i tak a tolik duplicit navic… :\
h4kuna
Backer | 740
+
0
-

pekelnik napsal(a):

@h4kuna mas to pekne zpracovany :) o tom zadna…

Děkuji

Ja gettext nepouzivam. Vadi mi na nem 2 veci:

  • poedit
  • nutnost psat plural vsude kde ho chci pouzit – s preklady je prace i tak a tolik duplicit navic… :\
  • poedit beru jako výhodu takové GUI nad xgettextem, vytáhnu si texty vrazím je někomu na zkontrolování a nemusí procházet aplikaci a najde překlepy
  • plurál ano musíš a zase kolikrát ho použiješ? A kolikrát v aplikaci napíšeš například slovo email :)

Pak tu jsou výhody

  • kešování binárního slovníku
  • nativní php (rychlost)

Jak jsi psal s překládáním aplikace jsou celkem patálie, a každý způsob má své neduhy a tyto mi zatím příjdou přijatelné.

Editoval h4kuna (22. 11. 2012 21:33)

h4kuna
Backer | 740
+
0
-

pekelnik napsal(a):

@h4kuna mas to pekne zpracovany :) o tom zadna…

  • nutnost psat plural vsude kde ho chci pouzit – s preklady je prace i tak a tolik duplicit navic… :\

Tak jsem zjistil že tento bod není úplně pravdivý, pomocí lehké kličky se nechá obejít a plurál používáš jednou z katalogu a pokud v něm budeš mít překlep upravuješ ho na jednom místě a projeví se všude. Bude-li zájem předvedu.

h4kuna
Backer | 740
+
0
-

Aktualizoval jsem dokumentaci

pekelnik
Člen | 462
+
0
-

Opravil jsem ti tam typo :)

btw. nelibi se mi ty vykricnicky: {!_'...'} – jsou tam snad nutne?

Editoval pekelnik (9. 2. 2013 19:37)

h4kuna
Backer | 740
+
0
-

Pěkně děkuji,

vykřičník vypína escapování a u statických textů není potřeba escapovat. Ale začátečníky by to mohlo mást nebo proč myslíš abych to vyhodil?

Editoval h4kuna (9. 2. 2013 21:32)

pekelnik
Člen | 462
+
0
-

Podle me by se melo escapovat vsechno co jde na vystup. Vykon to neovlivni (meritelne). Vypnuti escapovani v dokumentaci nabada k bad practice. Nikde neni napsano ze ty texty jsou bezpecne. Krome toho to vypada sloziteji nez bez toho vykricniku.

{_'...'} vs. {!_'...'}
Jan Tvrdík
Nette guru | 2595
+
0
-

h4kuna wrote: u statických textů není potřeba escapovat.

Jak to? Co když se v překladu vyskytne třeba ampersand?

h4kuna
Backer | 740
+
0
-

pekelnik napsal(a):

Nikde neni napsano ze ty texty jsou bezpecne.

To vychází z toho, aby fungovalo čtení textů ze souborů pomocí poeditu tak texty musí být staticky.

{!_'Hi'}

se přeloží na

echo gettext('Hi');

Nejde udělat.

{!_$foo}

přeloženo na

echo gettext($foo);

Ono se to takto přeloží ale přestane ti fungovat vyhledávání textů poeditem.

Jediný kde escapování nechat je když nahrazuješ.

{_'Heslo bylo odesláno na váš email %s', $email}

Je to na uvážení programátora, ale asi máš pravdu v tom že to dramaticky výkon nemění a vede to k bad practice a v ukázce by takový věci na hraně ano nebo ne být neměli.

Jan Tvrdík napsal(a):

h4kuna wrote: u statických textů není potřeba escapovat.

Jak to? Co když se v překladu vyskytne třeba ampersand?

Máš pravdu, ale pořád je to na zodpovědnosti programátora. Jde o to že ty předem znáš co to bude za texty.

Editoval h4kuna (10. 2. 2013 9:02)

Jan Tvrdík
Nette guru | 2595
+
0
-

h4kuna wrote: Jde o to že ty předem znáš co to bude za texty.

Ale neznáš předem překlad. Ani {!_'Hi'} není dobrý nápad. Je to náchylné na to, že někdo (nemusí to být ani programátor) upraví text a zapomene odstranit vykřičník. Prostě nedává smysl psát víc a úmyslně si tak snížit bezpečnost aplikace.

hrach
Člen | 1838
+
0
-

Nevím jestli si překládáš blog nebo co, ale většinou všechny překlady dělají externí firmy, kterým posleš xls/csv a pak si ho naparsuješ. Jejich překladatelé opravdu neví, co je XSS a že nemají použít &<>.

Editoval hrach (10. 2. 2013 15:59)

h4kuna
Backer | 740
+
0
-

Jan Tvrdík napsal(a):

Ale neznáš předem překlad.

Zrovna u překladů čtené ze slovníku nevím jestli by měl někdo úmysl ohrozit aplikaci.

Je to náchylné na to, že někdo (nemusí to být ani programátor) upraví text a zapomene odstranit vykřičník.

Ok chápu, v dokumentaci jsem to upravil.

Btw: taky jsem přidal automatickou detekci jazyka při první návštěvě stránek.

h4kuna
Backer | 740
+
0
-

Překladač v praxi:

ak-samol.cz

hajek-kaktusy.cz majitel pracuje s Poeditem a posílá nám zpátky přeložené *.po soubory.

Mám ještě další web, ale ten není ještě hotový.