Kompletní lokalizace Nette aplikací – GettextExtractor v2
- Karel Klíma
- Člen | 31
Pár slov úvodem: Na tomto fóru se objevují desítky dotazů, jak přeložit celou aplikaci napsanou v Nette do jiného jazyka, a to i včetně formulářů apod. Řešení, která se doteď dala používat, byla všechna dost polovičatá. Ukázalo se, že Konečné řešení lokalizace nebylo zas tak úplně konečné… Připoutejte se prosím, na scénu přichází nové eso – GettextExtractor v2
Co to je?
GettextExtractor je nástroj, který prochází soubory a hledá v nich
gettextové řetězce k přeložení. Z vyhledaných frází pak vytvoří
jeden human-readable balík v podobě *.po
nebo *.pot
souboru a drasticky tak usnadní překladateli práci.
Stažení:
Killer features
- Parsery pro PHP syntax i LatteFilter syntax (dříve CurlyBrackets)
- Podpora překladu formulářů
- Podpora překladu DataGridu
- Možnost nastavení stávajících parserů i vytvoření vlastních
- Funguje skvěle s GettextTranslatorem
Jak to použít
<?php
define('BASE_DIR', dirname(__FILE__));
define('APP_DIR', BASE_DIR . '/application');
require BASE_DIR . '/library/GettextExtractor/NetteGettextExtractor.php';
$ge = new NetteGettextExtractor(); // provede základní nastavení pro šablony apod.
$ge->setupForms()->setupDataGrid(); // provede nastavení pro formuláře a DataGrid
$ge->scan(APP_DIR); // prohledá všechny aplikační soubory
$ge->save(APP_DIR . '/locale/myapp.en.po'); // vytvoří Gettextový soubor editovatelný např v Poeditu
?>
Definice vlastních pravidel
<?php
require dirname(__FILE__) . '/GettextExtractor/GettextExtractor.php';
$ge = new GettextExtractor('extractor.log') // průběh bude logován do souboru
$ge->removeAllFilters(); // zruší základní nastavení
$ge->setFilter('php', 'PHP'); // přiřadí PHPFilter příponě php
$ge->getFilter('PHP')->addFunction('translate')->addFunction('_'); // nastaví filtr PHP
?>
Více příkladů najdete přímo v distribuci.
Mám extrahováno, co dál?
Jakmile GettextExtractor vytvoří gettextový zdrojový soubor, mám vyhráno pouze z poloviny. Dále se nabízejí celkem tři možnosti:
- Jsme-li již v této fázi unavený a unuděný a znechucený, můžu se na lokalizaci vykašlat
- Můžu zkopírovat vytvořený soubour a ručně do něj dopsat překlady v nějakém textovém editoru.
- Můžu využít Poedit a pracovat s gettextem efektivně. Lze vytvořit nový katalog z POT souboru (což je šablona pro PO soubory), ten pohodlně upravit a následně uložit. Poedit již sám přeloží gettext do binárního MO souboru, což je cíl, kam se potřebujeme dostat. Tento MO soubor už může být zpracován například GettextTranslatorem
Související vlákna
https://forum.nette.org/…i-lokalizace
https://forum.nette.org/…tte-aplikaci
https://forum.nette.org/…-i18n-a-l10n
Co zbývá doladit
Především je potřeba vše otestovat a dále potom zjistit, jestli nechybí handlery pro některé formulářové nebo datagridové funkce. Kdo odhalí nějaký nedostatek, tomu budiž odměnou dobrý pocit v srdci :-) Budu rád za jakékoliv připomínky nebo nápady, jak by se tahle užitečná věcička dala ještě více zdokonalit.
- Ondřej Mirtes
- Člen | 1536
Ještě než to s chutí vyzkouším, zeptám se: vyžaduje to stále
escapování řetězců v šablonác {!_'string'}
nebo už mu
stačí {_'string'}
? Podporuje oboje?
Až se pustím do testování, určitě přijde více otázek :)
- hurvajs
- Člen | 86
Možná docela hloupá otázka, ale proč se všichni snažíte předělávat již dokonalý gettext v PHP? Osobně nechápu proč bych měl dělat lokalizace podle následujících kroků:
- napsat kód,
- vytvořit si PO soubory,
- následně přeložit např. EN → CZ,
- vygenerovat MO soubory,
- vytvořit objekt
translate
a zpětně rozparsovat binární MO soubory na text a jednotlivé klíče a překlady.
To je na mě nezlobte, ale je to nošení dříví do lesa. Bez problémů
mohu skončit na bodu 4) protože PHP si vše zařídí samo a nemusím se
o nic starat. Nehledě na to, že silně pochybuji, že by se objekt
translate
nemusel kešovat.
- norbe
- Backer | 405
hurvajs napsal(a): …
Přijde mi, že jsi moc nepochopil, k čemu tenhle script vlastně slouží. GettextExtractor neslouží k samotnému překladu. Jedná se o script, který ve spojení s Poeditem automaticky vytáhne texty, které je potřeba přeložit. To si myslím, že je velmi užitečný.
To jestli pak budeš používat pro překlad gettext, nebo jiný řešení je už na Tobě.
- hurvajs
- Člen | 86
Ano, to vim, k cemu slouzi. Ale na to je hotovy uz hoooodne davno xgettext,
ktery ti prijde co chces a vygeneruje PO soubory. Takze je to k nicemu –
myslim GettextExtractor
.
Nehlede na to, ze POEdit je dost spatny. 100% lepsi je proste upravit soubor rucne. PO je v podstate textovy soubor a staci jen znat jeho format.
- Karel Klíma
- Člen | 31
LastHunter napsal(a):
Ještě než to s chutí vyzkouším, zeptám se: vyžaduje to stále escapování řetězců v šablonác
{!_'string'}
nebo už mu stačí{_'string'}
? Podporuje oboje?
Podporuje oboje. Dokonce podporuje libovolný prefix (i více prefixů), který se nadefinuje.
hurvajs napsal(a):
Možná docela hloupá otázka, ale proč se všichni snažíte předělávat již dokonalý gettext v PHP? Osobně nechápu proč bych měl dělat lokalizace podle následujících kroků:
- napsat kód,
- vytvořit si PO soubory,
- následně přeložit např. EN → CZ,
- vygenerovat MO soubory,
- vytvořit objekt
translate
a zpětně rozparsovat binární MO soubory na text a jednotlivé klíče a překlady.
S GettextExtractorem body 1) a 2) odpadají, bod 5) záleží už čistě na implementaci překladového adaptéru.
To je na mě nezlobte, ale je to nošení dříví do lesa. Bez problémů mohu skončit na bodu 4) protože PHP si vše zařídí samo a nemusím se o nic starat. Nehledě na to, že silně pochybuji, že by se objekt
translate
nemusel kešovat.
To je pravda. Někomu ale nativní podpora gettextu v PHP nemusí nutně vyhovovat, zvlášť nakládání s plurály je docela podivné. Implementace vlastního adaptéru pro překlad pak vývojáři umožní aplikace/stránky dělat přesně tak, jak potřebuje.
A propo, vsechny uváděné Killer features umí sám o sobě xgettext ;-) Takze se v podstatě nejedná o žádné killer…
A zvládne obyčejný smrtelník nakonfigurovat xgettext, aby dělal přesně tohle, za dvacet vteřin? Půvab tohoto řešení spočívá v tom, že je již přesně připravené na práci s Nette a šablonami, resp. LatteFilterem. V tomhle to xgettext trumfne na celé čáře, protože upřímně, komu by se chtělo psát vlastní parser pro xgettext?
hurvajs napsal(a):
Ano, to vim, k cemu slouzi. Ale na to je hotovy uz hoooodne davno xgettext, ktery ti prijde co chces a vygeneruje PO soubory. Takze je to k nicemu – myslim
GettextExtractor
.Nehlede na to, ze POEdit je dost spatny. 100% lepsi je proste upravit soubor rucne. PO je v podstate textovy soubor a staci jen znat jeho format.
S některými tvrzeními bych byl opatrný. Přece jenom může existovat někdo, kdo nesdílí stejné názory.
Editoval Karel Klíma (22. 10. 2009 15:25)
- hurvajs
- Člen | 86
Karel Klíma napsal(a):
S GettextExtractorem body 1) a 2) odpadají, bod 5) záleží už čistě na implementaci překladového adaptéru.
Odpadaji? Tomu moc nerozumim. Myslel jsem napsat samotnou aplikaci v Nette.
Body 1), 2) a 4) jsou proste nutne. Pro POEdit jsou nutne PO soubory, takze se
musi bud pouzit xgettext
nebo Gettextextractor
. Ale
vysledek jsou nutne PO soubory. A jak jsem uvedl, mam radeji cista reseni, na
gettext existuje velice dobry programek xgettext
a umi vse co umi
GettextExtractor
.
To je pravda. Někomu ale nativní podpora gettextu v PHP nemusí nutně vyhovovat, zvlášť nakládání s plurály je docela podivné. Implementace vlastního adaptéru pro překlad pak vývojáři umožní aplikace/stránky dělat přesně tak, jak potřebuje.
Podotykam, ze u sebe samotneho nevidim duvod, proc bych mel pouzivat nejakou
nahradu za gettext. Stejne v kodu pisi _('gettext is perfect')
,
tak mohu nechat preklad primo na gettextu. Reseni bude na 100% rychlejsi, nemusi
se kesovat (uz si to kesuje Apache). Drtiva vetsina hostingu ma gettext zapnuty,
takze opravdu nevidim duvod pouzivat neco jineho. Dalsi nespornou vyhodou, je
treba v Linuxu se gettext pouziva na lokalizace aplikaci.
Plural ze je spatne? He, to je docela zajima informace. Pouzivam gettext asi tak 6 let a jeste jsem nemel problem, ze bych mel spatne sklonovanou cestinu napriklad.
A zvládne obyčejný smrtelník nakonfigurovat xgettext, aby dělal přesně tohle, za dvacet vteřin? Půvab tohoto řešení spočívá v tom, že je již přesně připravené na práci s Nette a šablonami, resp. LatteFilterem. V tomhle to xgettext trumfne na celé čáře, protože upřímně, komu by se chtělo psát vlastní parser pro xgettext?
Nemusi se nic psat. Implementovano jiz v OS. Takze pokud clovek spusti
xgettext
s prislusnymi parametry (treba jake typy souboru ma
prohledat), tak mu to vyplivne PO. Cele kouzlo. Zalezitost na 1 sek. Pak
upravim v text. editoru PO a preklady klicu, pregeneruji do binarnich MO a mam
hotovo.
S některými tvrzeními bych byl opatrný. Přece jenom může existovat někdo, kdo nesdílí stejné názory.
S jakymi tvrzenimi? To ze je POEdit na dve veci? Na nic a na smazani. Za tim si stojim… :-D
Samozrejme, chapu ze neco nemusi vyhovovat vsem, kazdy ma jine naroky. Nikomu nic neberu. Jen jsem se ptal, proc se „v uvozovkach“ delaji nektere veci znova, kdyz na to jiz existuji silne nastroje.
- redhead
- Člen | 1313
Taky zajímavá myšlenka, proč se věci dělají znova?
To je jakoby proč by měli být všechny distribuce linuxu, když už je windows, nebo naopak. Nebo proč vlastně David dělá Nette, když je už celá řada jinejch frameworků, který dělají to samé a ještě víc (btw. na nette nedám dopustit)?? Proč je Photoshop, když už je Gimp?
Nemám linux, čili říkám hned, že to (nejspíš, nevím zdali je nějaká windows verze) například já nerozjedu. Navíc mám averzi k těmhle konzolovým přepínačovým programům.
Nevím zdali je rychlejší napsat tenhle command, než jenom dát v prohlížeči F5! Pro mě určitě ne!
Nechci žádný flamewar, jen jsem chtěl trochu vyjádřit i svůj názor na to co jsi tu řekl. Nemám nic proti xgettext, jen chci říct, že každý může používat to co má radši. Není to o tom, že je tu jeden nástroj, že ho hned musí používat všichni a nemůže být jiný.
Já osobně jsem za tohle rád.
S pozdravem
redhead
- hurvajs
- Člen | 86
Vsak ja to nikomu neberu. Ja pouzivam xgettext
, jsem s nim
spokojen. Puvodne jsem se ptal, proc p. Klima se psal
GettextExtractor
kdyz na to uz jsou hotove veci a dobre. Ze
v podstate se tim nahrazuje funkcionalita gettextu. Ale to je jedno. nicmene,
klobouk dolu, protoze na tom musel nechat nejakou tu hodinu a udelat to.
GettextExtractor a gettext neni preci o F5 v browseru, ale o tom jak vytahnout klice, ktere se pak prekladaji. Alespon tak chapu ja fci GettextExtractoru.
Verim, ze nekomu to opravdu pomuze. Me asi ne. Samozrejme nechavam kazdemu pravo volby, at pouziva co chce.
Ja bych byl treba rad za mnohem obsirnejsi dokumentaci a priklady – neco jako ZF. Taky kazdy z Vas/nas musi uznat, ze Nette dost pokulhava, ikdyz se na tom podle p. Grudla urputne pracuje. Jen to prosim, nikdo neberte spatne nebo navazeni se do Nette ;-)
- hurvajs
- Člen | 86
jasir napsal(a):
Mohu poprosit o další poučení? Jak na to tedy s xgettextem? Děkuji.
Třeba takto:
find ./ -name \*.php | xargs xgettext --no-wrap --from-code=utf-8 --language=PHP
Čímž vytáhneš gettext ze všech PHP souborů. Lze to jednoduše
rozšířit i na šablony či cokoliv jiného. Samozřejmě
xgettext
má mnohem více možností.
- redhead
- Člen | 1313
No právě že F5 v prohlížeči stačí pro vytáhnutí těch klíčů. O to jde.
Píšu si do aplikace texty, skočím do browseru, F5, skočím do PoEditu a překládám, CTRL+S, skočím do browseru F5 a všechno krásně přeloženo.
Myslím, že je to prostě komfort, který se mě osobně líbí! Jen tak dál..
- hurvajs
- Člen | 86
Hmm, tak to v podstate stejny postup jako mam ja, jen s tim rozdilem, ze ja misto F5 pouziji bash, misto POedit VIM. Jinak je to uplne stejne a stejny komfort ;-). A pokud se nejedna o prvotni parsovani gettextu, tak vlezu do administrace a menim preklady tam.
Editoval hurvajs (22. 10. 2009 18:11)
- jasir
- Člen | 746
hurvajs napsal(a):
jasir napsal(a):
Mohu poprosit o další poučení? Jak na to tedy s xgettextem? Děkuji.
Třeba takto:
find ./ -name \*.php | xargs xgettext --no-wrap --from-code=utf-8 --language=PHP
Čímž vytáhneš gettext ze všech PHP souborů. Lze to jednoduše rozšířit i na šablony či cokoliv jiného. Samozřejmě
xgettext
má mnohem více možností.
Díky. Ale vytáhne to i ze šablon konstrukce {_
a
{_!
a volání translate() metod? Volání php funkce to jistě
zvládá, jde mi o tyto konkrétní věci. Používám tedy také windows a pod
ním cygwin.
- romansklenar
- Člen | 655
hurvajs napsal(a):
Reseni bude na 100% rychlejsi, nemusi se kesovat (uz si to kesuje Apache).
Nevíš jestli se nějak nedá vynutit, aby si Apache .mo soubor nakešoval znovu?
- wdolek
- Člen | 331
vzhledem k tomu, ze jsem s GetTextem nikdy nepracoval, mam trosku problémy pochopit, jak to cele funguje. z prikladu z archivu jsem se toho moc nedozvedel – respektive sem si mohl zacit myslet neco o zahadne magii, kdy tento program nejak precte vsechny skripty, a nejak nahradi (?) / prelozi texty treba v popisku formularovych prvku.
nanestesti to je v ostrem kontrastu s tim malem, co o gettextu vim –
tedy ze se pouziva funkce gettext( )
nebo jeji alias
_( )
. tuto funkci musim uvest vsude, kde chci, aby se texty
prekladaly + vyrobit .po
soubor, prelozit, umistit na web
.mo
soubor, a pridat nekam na zacatek inicializaci gettextu…
takze :) odpustte mi muj skromny duvtip (respektive velkolepy neduvtip), ale
poradi mi nekdo, co vse musim udelat, kdyz mam nyni web kompletne v cestine
(nikde zadne volani _( )
nebo jakesi translate
funkce
(co je to zac?)) a chci vyrobit anglickou mutaci? (predpokladam, ze musim
zeditovat vsechny texty a nacpat je do _( )
– ale jak rikam,
z ukazek jsem moc nepobral, jestli to je automatizovane, nebo ne…
pak nejakou editaci pomoci Poeditu jeste chapu… a pak zase zpetne namontovani
do Nette – to uz mi take neni jasne)
predem diky :)
- Karel Klíma
- Člen | 31
wdolek napsal(a):
vzhledem k tomu, ze jsem s GetTextem nikdy nepracoval, mam trosku problémy pochopit, jak to cele funguje. z prikladu z archivu jsem se toho moc nedozvedel – respektive sem si mohl zacit myslet neco o zahadne magii, kdy tento program nejak precte vsechny skripty, a nejak nahradi (?) / prelozi texty treba v popisku formularovych prvku.
nanestesti to je v ostrem kontrastu s tim malem, co o gettextu vim – tedy ze se pouziva funkce
gettext( )
nebo jeji alias_( )
. tuto funkci musim uvest vsude, kde chci, aby se texty prekladaly + vyrobit.po
soubor, prelozit, umistit na web.mo
soubor, a pridat nekam na zacatek inicializaci gettextu…takze :) odpustte mi muj skromny duvtip (respektive velkolepy neduvtip), ale poradi mi nekdo, co vse musim udelat, kdyz mam nyni web kompletne v cestine (nikde zadne volani
_( )
nebo jakesitranslate
funkce (co je to zac?)) a chci vyrobit anglickou mutaci? (predpokladam, ze musim zeditovat vsechny texty a nacpat je do_( )
– ale jak rikam, z ukazek jsem moc nepobral, jestli to je automatizovane, nebo ne… pak nejakou editaci pomoci Poeditu jeste chapu… a pak zase zpetne namontovani do Nette – to uz mi take neni jasne)predem diky :)
Pokud aplikace pro překlad není připravená, bude se muset upravit.
(Nette)GettextExtractor umí automaticky vytáhnout řetězce pro překlad
třeba z formulářů, ale z šablon už ne – tam je třeba každou frázi
hodit do makra {_"Něco na překlad"}
, respektive
{!_"Něco na překlad s escapováním"}
(pokud je použit
LatteFilter). Z tohoto zápisu si to už umí GettextExtractor vytáhnout.
Naproti tomu pokud je v šabloně třeba něco jako
<p>Věta v odstavci</p>
, pak to ignoruje.
Pro lokalizaci celé aplikace je třeba učinit tyto kroky:
- Upravit šablony podle vzoru výše, viz filtr Latte
- Vytvořit soubor podobný souboru
Examples/NetteGettextExtractor.php
v distribuci. Zde je potřeba akorát správně nastavit, kde všude se má hledat (metodaGettextExtractor::scan()
) a kam se to pak má uložit (metodaGettextExtractor::save()
). Obě dvě jsou v tomto příkladu k nalezení. - Spustit soubor z předchozího bodu (například skrz prohlížeč)
- Zkopírovat vygenerovaný
*.po(t)
soubor a přeložit v Poeditu. Kopírování silně doporučuji, protože při každém spuštění GettextExtractoru se vygenerovaný soubor přepíše a zmizí tak veškerá manuálně vytvořená data (překlady). - Použít GettextTranslator,
který nevyžaduje přímou podporu gettextu, nebo si napsat vlastní
Translator, který bude využívat nativní gettextové funkce
gettext
angettext
.
- vladik
- Člen | 3
Ahoj Karle myslíš, že by jsi mohl udělat konkrétní příklad buď video nebo podrobný popis? Já s Nette teprve začínám, ale nevím kde uvedenou část kódu vložit …do index.php nebo do šablony @layout.phtml ?
Adresář GettextExtractor jsem nakopíroval do adresáře libs a v adresáři app mám adresář locale. Knihovnu GettextTranslator.php mám v libs/Nette.
Jak dál pokračovat?
děkuji ua info
- Karel Klíma
- Člen | 31
vladik napsal(a):
Ahoj Karle myslíš, že by jsi mohl udělat konkrétní příklad buď video nebo podrobný popis? Já s Nette teprve začínám, ale nevím kde uvedenou část kódu vložit …do index.php nebo do šablony @layout.phtml ?
Adresář GettextExtractor jsem nakopíroval do adresáře libs a v adresáři app mám adresář locale. Knihovnu GettextTranslator.php mám v libs/Nette.
Jak dál pokračovat?
Vezmi soubor Examples/NetteGettextExtractor.php
a zkopíruj ho
do stejný složky jako je index.php (složka public například podle suggested
directory structure). Pak soubor uprav a nastav mu správně cesty, tzn. změň
ho nějak takhle:
<?php
echo '<pre>';
echo 'NetteGettextExtractor';
require_once dirname(__FILE__) . '/../libs/GettextExtractor/NetteGettextExtractor.php';
$ge = new NetteGettextExtractor();
$ge->setupForms();
$ge->setupDataGrid();
$ge->scan(dirname(__FILE__) . '/../app');
$ge->save(dirname(__FILE__) . '/../app/locale/translation.po');
echo '</pre>';
?>
Snad jsem tam někde neudělal chybu… Dále už stačí jenom zobrazit soubor NetteGettextExtractor.php v prohlížečí a spuštěný skript pak vytvoří soubor translation.po v adrešáři app/locale.
Pro použití GettextTranslator viz jeho dokumentaci.
- Patrik Votoček
- Člen | 2221
Karel Klíma napsal(a):
- Zkopírovat vygenerovaný
*.po(t)
soubor a přeložit v Poeditu. Kopírování silně doporučuji, protože při každém spuštění GettextExtractoru se vygenerovaný soubor přepíše a zmizí tak veškerá manuálně vytvořená data (překlady).
A nešlo by udělat něco jako metodu saveMerge()
aneb že by
to spojilo prave vygenerovany *.po(t)
soubor se souborem ktery už
obsahuje nějáké překlady?
- Karel Klíma
- Člen | 31
vrtak-cz napsal(a):
Karel Klíma napsal(a):
- Zkopírovat vygenerovaný
*.po(t)
soubor a přeložit v Poeditu. Kopírování silně doporučuji, protože při každém spuštění GettextExtractoru se vygenerovaný soubor přepíše a zmizí tak veškerá manuálně vytvořená data (překlady).A nešlo by udělat něco jako metodu
saveMerge()
aneb že by to spojilo prave vygenerovany*.po(t)
soubor se souborem ktery už obsahuje nějáké překlady?
Bylo by to proti logice věci. Tohle jsou argumenty, proč to neimplementovat:
- Podporuje to přímo Poedit.
POT
soubory jsou jakési šablony, které mají obsahovat pouze nepřeložené fráze, složí jako vzor. Poedit pak umí z těchto souborů udělat updatePO
souboru, a to tak, že se zachovají pouze fráze, které jsou vPOT
souboru. Jinými slovy – fráze, které v aplikaci nejsou, se vymažou. - Lokalizace většinou počítá s větším množstvím jazyků. Měly by se pak mergovat všechny soubory? Jednoduše řečeno, zdroj a výsledek by měly zůstat odděleny.
- vladik
- Člen | 3
Ahoj Karle,
tak jak jsi mi poradil, tak to opravdu zafungovalo. Nicméně byl vytvořen
jen jeden soubor translation.po
Proto abych měl více překladů jsem si vytvořil strukturu
locale/cs/LC_MESSAGES/messages.po pak locale/en/LC_MESSAGES/mesages.po
locale/sk/LC_MESSAGES/messages.po atd.
otázka
1. Když mám vygenerovaný soubor .po z řetězců, které jsou
v šabloně česky {!_"Něco na překlad s escapováním"}
tak, v souboru locale/cs/LC_MESSAGES/messages.po bude jak originál tak
i překlad česky?
2. Když jsem použil {!_"Něco na překlad s escapováním"} tak mi to vyhodilo chybovou hlášku
MemberAccessException
Call to undefined method Template::translate().
3. Jakou definici mám použít pro přepínání jazykových verzí?
a tuto definici mám uložit do index.php v adresáři www nebo do šablony
@layout.phtml v adresáři Template?
děkuji za radu
Vladik
- Karel Klíma
- Člen | 31
vladik napsal(a):
tak jak jsi mi poradil, tak to opravdu zafungovalo. Nicméně byl vytvořen jen jeden soubor translation.po
Proto abych měl více překladů jsem si vytvořil strukturu locale/cs/LC_MESSAGES/messages.po pak locale/en/LC_MESSAGES/mesages.po locale/sk/LC_MESSAGES/messages.po atd.
To jsi udělal správně. Přesně tak to má fungovat.
otázka
1. Když mám vygenerovaný soubor .po z řetězců, které jsou v šabloně česky {!_"Něco na překlad s escapováním"}
tak, v souboru locale/cs/LC_MESSAGES/messages.po bude jak originál tak i překlad česky?
Ano. Nebo to můžeš úplně vynechat. Sice bych osobně doporučil do šablon nepsat diakritiku (i když všechno běží v unicode), ale i takhle se to dá řešit.
2. Když jsem použil {!_"Něco na překlad s escapováním"} tak mi to vyhodilo chybovou hlášku
MemberAccessException
Call to undefined method Template::translate().
Hm… Není nějaký problém s definicí helperu ‚translate‘? Jakým
způsobem inicializuješ Translator? Pokud můžeš, používej radši verzi bez
vykřičníku, tj. {_"Něco"}
.
3. Jakou definici mám použít pro přepínání jazykových verzí?
a tuto definici mám uložit do index.php v adresáři www nebo do šablony @layout.phtml v adresáři Template?
To závisí čistě na tobě. Implementace by měla být každopádně v buď v indexu (respektive bootstrapu) nebo v presenteru. Překladovou logiku bych v šabloně určitě neřešil.
- wdolek
- Člen | 331
inu, tak jsem si s tim chvilku hral, postupoval podle navodu, ale bez vysledku
- prepsal sem sablony na volani
{_" "}
- projel sem GettextExtractorem projekt
- pomoci POEditu prelozil (cs → en)
- soubor
.mo
jsem nahral doapp/locale/en/LC_MESSAGES/messages.mo
- pridal do
DefaultPresenter
do metodybeforeRender
prirazeni prekladace sablony (ne vsechny presentery potrebuju prekladat – administracni presenter je pouze v cestine, default je v cestine i anglictine) - smazal
app/temp
… ale nic :(
sablona:
<a href="#">{_"Kniha návštěv"}</a>
DefaultPresenter:
protected function beforeRender() {
// translator
$translator = new Translator($this->lang, (APP_DIR . '/locale'));
$this->template->setTranslator($translator);
...
}
… skutecne $this->lang
obsahuje en
pro
anglictinu, cs
pro cestinu
jako transrator jsem si vzal ten co je na http://charlie.cz/…t-extractor/
mimochodem, takto vypada muj translatoidni skript
<?php
echo '<pre>';
require_once dirname(__FILE__) . '/NetteGettextExtractor.php';
$ge = new NetteGettextExtractor();
$ge->setupForms();
$ge->scan(array('../app/models/', '../app/templates/Default/', '../app/templates/@layout.phtml'));
$ge->save('nette.po');
echo '</pre>';
prekvapilo me ale, ze v prekladech sem mel pouze veci ze sablon, nic
z formularu (cesty sedi). .po
soubor obsahoval pouze veci z
@layout.phtml
a default.phtml
- vladik
- Člen | 3
Ahoj,
rád bych ještě požádal o radu…já když použiji {_"Kniha návštěv"} v šabloně v adresáři template
tak mi to vyhodí chybu
MemberAccessException
Call to undefined method Template::translate().
Line 223: foreach ($this->helperLoaders as $loader) {
Line 224: $helper = call_user_func($loader, $lname);
Line 225: if ($helper) {
Line 226: $this->registerHelper($lname, $helper);
Line 227: return call_user_func_array($helper, $args);
Line 228: }
Line 229: }
Line 230: return parent::__call($name, $args);
Line 231: }
Line 232:
Line 233: return call_user_func_array($this->helpers[$lname], $args);
Line 234: }
Line 235:
Line 236:
Line 237:
nevím, kde mám co definovat
také nevím jak nadeginovat v hlavičce šablony aby se defaultně použila čeština
a jak volat v odkazu jiné překlady?
<a href="http://www.pokus.cz"><img src="{$baseUri}images/cs.gif" alt="Čeština (Česká republika)" title="Čeština (Česká republika)" /></a>
děkuji za info
Vladik
Editoval vladik (7. 11. 2009 21:36)
- Karel Klíma
- Člen | 31
Kevas napsal(a):
Ahoj,
je verze php 5.2.2 a vyšší důležitá pro funkčnost? Mám totiž na hostingu verzy 5.2.0–8+etch15.
Děkuji
Nejsem si jistý. Pravděpodobně tam to omezení je kvůli Tokenizeru, ale nedá se vyloučit, že knihovna bude správně pracovat i v nižších verzích PHP.
- ji_ri_k
- Člen | 44
Laboruji teď také s gettextem, ale nedaří se mi jak bych chtěl. Nikdy jsem s tímto nástrojem nepracoval, proto se na vás obracím. V šabloně mám:
<p>{_'You have %s new message.', 1}</p>
Při použití GettextExtractoru mi to tento text ze šablony do .po souboru
nevytáhne. Najde to jen {_'You have %s new message.'}
. Jakým
jiným způsobem ve windows je možno tyto soubory vytáhnout?
Další problém mám s plurály. Jakým způsobem to mám do šablony zadat? Stačí to zanechat takto? {_'You have %s new message.', 1} a pak to v .po souboru doeditovat?
A jak v např. v Poeditu ty plurály doplním? Nikdy se mi tam možnost je zadat nezobrazila.
Lokalizaci webů jsem řešil vždy jinými způsoby a rád bych se seznámil s tímto řešením, budu rád, když mi někdo pomůžete. Teď v tom bohužel plavu jak kámen v rybníku…
- dotTwelve
- Člen | 167
Pouzivam aplikaci s moduly a tato vyjimka se mi vyhodi pri zavolani gettext.php
Cannot load presenter 'Gettext:Php', class 'Gettext_PhpPresenter' was not found in 'www/document_root/../app/GettextModule/presenters/PhpPresenter.php'.
Obsah gettext.php
<?php
define('BASE_DIR', dirname(__FILE__));
define('APP_DIR', BASE_DIR . '/app');
require BASE_DIR . '/libs/GettextExtractor/NetteGettextExtractor.php';
$ge = new NetteGettextExtractor(); // provede základní nastavení pro šablony apod.
$ge->setupForms()->setupDataGrid(); // provede nastavení pro formuláře a DataGrid
$ge->scan(APP_DIR); // prohledá všechny aplikační soubory
$ge->save(APP_DIR . '/locale/front/template.po'); // vytvoří Gettextový soubor editovatelný např v Poeditu
?>
- ji_ri_k
- Člen | 44
ji_ri_k napsal(a):
Laboruji teď také s gettextem, ale nedaří se mi jak bych chtěl. Nikdy jsem s tímto nástrojem nepracoval, proto se na vás obracím. V šabloně mám:
<p>{_'You have %s new message.', 1}</p>
Při použití GettextExtractoru mi to tento text ze šablony do .po souboru nevytáhne. Najde to jen
{_'You have %s new message.'}
. Jakým jiným způsobem ve windows je možno tyto soubory vytáhnout?Další problém mám s plurály. Jakým způsobem to mám do šablony zadat? Stačí to zanechat takto? {_'You have %s new message.', 1} a pak to v .po souboru doeditovat?
A jak v např. v Poeditu ty plurály doplním? Nikdy se mi tam možnost je zadat nezobrazila.
Lokalizaci webů jsem řešil vždy jinými způsoby a rád bych se seznámil s tímto řešením, budu rád, když mi někdo pomůžete. Teď v tom bohužel plavu jak kámen v rybníku…
Tak jsem se k tomu dnes opět dostal, ale koukám, že odpověď jsem nedostal. Možná jsem se špatně zeptal.
Některé části jsem dnes vyřešil, ale co se mi stále nedaří je
vytažení všech textů do .po souboru.
Proto by mne zajímalo, jakým způsobem vytahujete z phtml šablon texty
k překladu?
např.:
{_'You have %s new message.', 1}
- iguana007
- Člen | 970
Mám podobný problém a nedaří se mi jej vyřešit: https://forum.nette.org/…i-lokalizace?…
- ClaryAldringen
- Člen | 5
Zdravím, mám takový problém s Translatorem. Všechny texty se v pořádku přeloží, akorát v polích, kde je prázdná EmptyValue se nachází tento text:
Project-Id-Version:
POT-Creation-Date:
PO-Revision-Date:
Last-Translator: Martin Zadražil <zadram1@gmail.com>
Language-Team:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Nevíte někdo jak se tohoto zbavit? Díky
- Jarda
- Člen | 25
Ahoj, zkouším toto chytré řešení, ale zápasím s poEditem. Jak ho
přinutím, aby mi nabídl zápis 3 plurálů pro
řetězec: I see %d little indians!
katalog mám nastavený dle návodu na plurály:
nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4 ? 1 : 2);
přesto mi poedit nabízí ke klíči pouze jeden překlad a nikde se mi nepodařilo vygooglit jak na to.
Předem díky za pomoc
verze poeditu: 1.4.6 (win)
- Lopo
- Člen | 277
Jarda napsal(a):
Ahoj, zkouším toto chytré řešení, ale zápasím s poEditem. Jak ho přinutím, aby mi nabídl zápis 3 plurálů pro řetězec:
I see %d little indians!
katalog mám nastavený dle návodu na plurály:
nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4 ? 1 : 2);
přesto mi poedit nabízí ke klíči pouze jeden překlad a nikde se mi nepodařilo vygooglit jak na to.
Předem díky za pomoc
verze poeditu: 1.4.6 (win)
skus
nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4 ? 1 : 2));
mam totiz dojem ze najprv priradi do premennej vysledok (n==1) a to potom posuva do ternaru
Editoval Lopo (3. 6. 2010 7:27)
- Jarda
- Člen | 25
tak po dalším experimentování jsem zjistil, že nakonec byla chyba v .po souboru.
U plurálových forem musí být v .po souboru následující úprava
msgid "I see %d little indians!"
msgid_plural "I see %d little indians!"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
to jsem nevěděl a GettextExtractor udělá pouze
msgid "I see %d little indians!"
msgstr "I see %d little indians!"
Domníval jsem se, že plurály poedit nabídne automaticky u řetězců s
%d
.
Dá se to řešit nějak automatizovaně v GettextExtractoru nebo v poeditu? nebo se musejí plurály ručně doupravit?