Kompletní lokalizace Nette aplikací – GettextExtractor v2

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

Jarda napsal(a):

jj, už na to koukám, stačilo trochu poupravit a už jede jak po másle. GettextExtractor je vážně kůl tůl :) Díky za něj!

A vytahuje ti to všechny řetězce ze šablon? Mě to pořád nefunguje. Stále najde jen něco …

newPOPE
Člen | 648
+
0
-

Chcem sa spytat na nazor, ako by ste videli generovanie .po suborov „realtime“ v devel rezime, resp. co prejde cez ->translate(...) a nie je to este pripravene na preklad zapisat zaznamenat do suboru?

vlna
Člen | 34
+
0
-

Ahoj,

resil se uz nejak problem s tim, GettextExtractor nebere tagy s parametrama ? Tzn. napr.: {_"HelloWorld %s", 1} ?

Jako rychly quickfix jsem drobne zmenil REGEXP v …\libs\GettextExtractor\Filters\NetteLateFilter.php:

class NetteLatteFilter implements iFilter
{
/* ... */
//hacked - jinak nenajde tagy, ktere maji parametry oddelene carkama
const LATTE_REGEX ='#{(__PREFIXES__)("[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')+(\s*,\s*.*?)*(\|[a-z]+(:[a-z0-9]+)*)*}#u';

… nemel jsem ale cas to moc testovat a vubec ten LatteFilter myslim neodpovida tomu, co je pouzity v posledni stable verzi Nette. Melo by ale asi stacit, aby ten regular proste matchnul tu prvni cast – obsah v uvozovkach a k tomu by to mohlo stacit.

Nicmene jeste mam problem, pokud pouziju tvar s parametrem {_"test %s", 1}, tak mi to funguje jen pro 1, cokoliv jineho se vubec neprelozi. Asi jsem celkove ten preklad blbe pochopil. Ten parametr musi bejt vzdycky cislo a on se snazi to nejak prevadet na plural? Nemuzu to parametrizovat libovolnym retezcem ? Nehazi mi to zadnou chybu, proste na cokoliv krome 1 se to prelozi na "" (prazdno).

Dik.

vlna
Člen | 34
+
0
-

Jeste dodatek. Viz dikuse nejsem jedinej zmatenej z pouziti extractoru + translatoru + poeditu. Nenasel by se dobrovolnik, kterej by strucne shrnul postup pouziti vseho dohromady s Nette v kratkym clanku aspon v add-ons ?

  • je to kompatibilni s posledni stable verzi Nette ? Nejakou dobu jsem Nette nesledoval, ale zda se, ze ten template filtr se zmenil.
iguana007
Člen | 970
+
0
-

Vlna: ono je vubec problem s temi regulary u obou extraktoru, ktere tady byly vytvorene (v1 a v2). Nevim jak vam, ale me ani jeden nefunguje spravne. Pouzivam pro extrakci POedit … s prvni verzi mi to jakz, takz funguje. A v2 mi nevytahne ze zdrojaku vubec nic. Mozna delam neco spatne, ale neni to ani nikde popsane (u teto v2 verze), jak to s poeditem rozchodit.
Pouzili jste nekdo tento v2 extractor s POEditem? Pokud ano, muzete sem hodit strucny popis toho, jak jste to rozchodili?
Diky.

norbe
Backer | 405
+
0
-

Spustím PHP kód, který pomocí GettextExtractoru vygeneruje POT soubor. V Poeditu pak mám otevřený PO soubor a kliknu na Katalog -> Aktualizovat z POT souboru, vyberu vygenerovaný soubor a je hotovo :)

vlna
Člen | 34
+
0
-

iguana007 napsal(a):

Nevim jak vam, ale me ani jeden nefunguje spravne.

Me V2 extractor i docela fungoval. Tj. tohle se spusti samostatne nad zadanyma adresarema (pres. ->scan(array(‚prvni‘,‚druhy‘)) – rekurzivne). V pripade php souboru to pouzije php filtr, v pripade templat LateFiltr a extrahuje to labely k prekladu.
Php filtr mi fungoval dobre, LateFiltr fungoval jen pro tagy bez parametru {_"neco"} ne {_"neco", 1, …}
Tohle u me rozchodila uprava Late filtru, kterou jsem psal v predchozim postu. Kdyztak to zkus.

Stale ale pretrvava problem s tim parametrizovanim, ke kteremu jeste doufam, v erudovany komunitni hint :-)

iguana007
Člen | 970
+
0
-

norbe napsal(a):

Spustím PHP kód, který pomocí GettextExtractoru vygeneruje POT soubor. V Poeditu pak mám otevřený PO soubor a kliknu na Katalog -> Aktualizovat z POT souboru, vyberu vygenerovaný soubor a je hotovo :)

Aha, ja byl prave zvykly dat jen „Aktualizovat“ a POEdit zavolal extractor a ten katalog ihned zaktualizoval … takhle by to tedy slo urcite taky, zkusim vc. upravy od Vlny z postu vyse.
Diky :o)

despiq
Člen | 320
+
-1
-

kaslete na poedit, je tu predci nette translation panel kterej je cuprovej

VeN
Člen | 46
+
0
-

Ahoj, stará se ještě někdo o ten NetteLatteFilter? Narážím také na problém, že se nenaleznou překlady s parametrem.

{_"Bla bla bla in %s online.", $foobar}

NetteLatteFilter řetězec z vesela ignoruje. Nepřijde mi, že by bylo tak těžké to ve filtru opravit. Takhle jsou akorát lidé nuceni psát špatné řetězce pro překlad.

newPOPE
Člen | 648
+
0
-

VeN napsal(a):

Zda sa ze ano, trochu som sa s tym hral nasiel som

NetteLatteFilter.php riadok 27 som si upravil takto a uz to berie, taky fast&furious fix kedze sa mi nechce studovat ten regEx :-D

<?php
	const LATTE_REGEX = '#{(__PREFIXES__)("[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\').*}#u';
?>
VeN
Člen | 46
+
0
-

Díky, vyzkouším to. Právě že se mi ten regulár taky nechce studovat :)

voda
Člen | 561
+
0
-

Na github.com/voda/gettext-extractor je vylepšená verze půodního extractoru. Umí extrahovat plurály i zprávy s kontextem (po vzoru gettextu).

Pro překlady používám translator založený ná php-gettextu, původní Nette translator jen tam kde to je nutné (formuláře, DataGrid).
V šablonách mám vlastní makra (+varianty s ‚!‘):

makro parametry
{_ singulár
{_n singulár, plurál, pocet
{_p kontext, singulár
{_np kontext, singulár, plurál, pocet

Vlastní překladač a makra v blízké době taky zveřejním.

Editoval voda (23. 12. 2010 12:53)

cooper
Člen | 2
+
0
-

Zdravím,

v jednom starším projektu používáme místo:

{_'Preloz me'}

tohle

{=_('Preloz me')}

Přepis do prvního tvaru je časově nemožný. Umíte mi někdo poradit, jak přinutit GettextExtractor v2 nebo xgettext, aby v Latte šabloně reagoval na tu druhou variantu a vyseparoval fráze pro překlad do PO souboru?

Díky, Cooper

Editoval cooper (8. 2. 2011 13:15)

hrach
Člen | 1834
+
0
-

jako rekni mi, kolikrat se ti v kodu vyskytuje tento sled znaku {=_(', aby si nemohl udelat hromadny replace?

Editoval hrach (8. 2. 2011 13:35)

cooper
Člen | 2
+
0
-

hrach napsal(a):

jako rekni mi, kolikrat se ti v kodu vyskytuje tento sled znaku {=_(', aby si nemohl udelat hromadny replace?

  1. No tak ještě by bylo potřeba nahradit i tu koncovou sekvenci ')} a to už nemusí být jednoznačný (všechny výskyty nebudou souviset s překlady)
  2. ono tam není jenom {=_(' ale i {= _(', {=_(", {= _(" a další kombinace
  3. kód jsem zdědil a HLAVNĚ vedení si nepřeje dělat velký zásahy + by se musel zavést ten nette translátor…

už jsem to vyřešil tak, že to parsuju jak zdroják C a funguje to, je to zvěř uznávám, ale takhle mám rozdaný karty ;-)…

marau
Člen | 50
+
0
-

Z hlavy:
Find what: \{= ?_\((‚|„)(.+?)(‘|“)\) ?\}
Replace with: {_($2)}

Dalo by se ještě upravit, ale pokud tam v téch řetézcích nemáš nějaký speciální blbosti, tak by jsi si s tím měl vystačit.

iguana007
Člen | 970
+
0
-

norbe napsal(a):

Spustím PHP kód, který pomocí GettextExtractoru vygeneruje POT soubor. V Poeditu pak mám otevřený PO soubor a kliknu na Katalog -> Aktualizovat z POT souboru, vyberu vygenerovaný soubor a je hotovo :)

Chtěl bych se zeptat, jak sis generoval ten POT soubor? Já to teď zkoušel metodou, že jsem vygeneroval PO – změnil mu hlavičky, ať sedí kódování s original POčkem, přejmenoval koncovku na POT a dal aktualizaci v POEditu. Je to takto správně nebo se to dělá jinak?
Díky za info.

voda
Člen | 561
+
0
-

iguana007 napsal(a):
Chtěl bych se zeptat, jak sis generoval ten POT soubor?

Normálně se to dělá tak, že se vygeneruje POT pomocí GettextExtractoru, což by měl být katalog všech textů, které se vyskytují ve zdrojácích. Potom vezmeš .po soubory a zaktualizuješ je podle POT šablony. Buď pomocí Poeditu nebo z příkazem msgmerge -Uv cs.po messages.pot (myslím, že Poedit ve skutečnosti taky volá msgmerge). To ti přidá nové texty, případně odstraní staré. Pak už jen zbývá doplnit nové překlady.
POT šablona by měla být normálním výstupem GettextExtractoru.

Editoval voda (3. 5. 2011 22:52)

iguana007
Člen | 970
+
0
-

Aha, takže ad příklad na začátku vlákna – mám správně volat:

$ge->save(APP_DIR . '/locale/myapp.en.pot');

což je víceméně to samé jako soubor s koncovkou „po“, akorát že obsahuje všechny texty aplikace a výše zmíněným příkazem si je zmerguju a získám tak aktualizovaný .po katalog

Díky za objasnění ;)

voda
Člen | 561
+
0
-

To „en“ bych z názvu vynechal, protože v POT šabloně žádný překlady nejsou (tzn. je pro všechny jazyky stejný):

$ge->save(APP_DIR . '/locale/myapp.pot');

Rozdíl mezi .pot a .po je ten, že v .pot nejsou vyplněny překlady (msgstr ""), info o jazyku, množných číslech, …

Jinak ještě doplním, že nemá smysl verzovat (třeba v gitu) .pot šablonu, protože ji vždy můžeš jednoduše získat spuštěním GettextExtractoru.

Edit:

Teď jsem ještě koukal na ten první příspěvek a původní Extractor skutečně vyráběl .po soubory, já používám upravený https://github.com/…xt-extractor, který má na výstupu .pot šablony.

Editoval voda (3. 5. 2011 23:59)

gawan
Člen | 110
+
0
-

voda napsal(a):
Vlastní překladač a makra v blízké době taky zveřejním.

Ahoj, rád by som použil tvoj extractor lebo asi ako jediný s nette extractorov pracuje aj s kontextom, ktorý občas musím využívať. Chcem sa opýtať: už si niekde zverejnil prekladač a makra?

voda
Člen | 561
+
0
-

@gawan: Makra a překladač jsou doplňcích, extractor je na githubu.

gawan
Člen | 110
+
0
-

@voda super ďakujem, nevšimol som si to.

Mám ešte jednu otázku. Dá sa scriptu gettext-extractor.php nejako zadať paramatre pot súboru ako charset a plural-forms? hlavne ten charset je problem lebo po každom pregenerovaní pot súboru musím ručne nastaviť charset v pot súbore, inak mi poedit zle zobrazí texty s diakritikou.

voda
Člen | 561
+
0
-

@gawan: V .pot souboru charset a plural-forms nejsou vůbec potřeba. Z něj se pouze pro každý jazyk vytváří .po soubory, kde už to nastavíš konkrétně pro daný jazyk.

gawan
Člen | 110
+
0
-

@voda: hmm… môj postup je:

  1. pridám do projektu nejaký text
  2. pregenerujem pot súbor.
  3. v poedite v menu „Katalóg“ → „Aktualizovať z POT súboru…“

následne mi poedit zahlási chybu: „Aktualizácia katalógu zlyhala“

A problém je, že POT súbor nemá nastavené kódovanie. A potom všetky texty s diakritikou sú zlé a nevedia sa napárovať s tými v PO súbore, ktorý už má nastavený charset. Ak ručne pridám charset do POT súboru aktualizácia prebehne v poriadku. Možno používam nejaký nevhodný postup ráce. Snažil som sa aj poedite niekde nastavit default kódovanie ale nič také som nenašiel. Asi to berie len z toho súboru. Ty to ako robíš? Tebe to nerobí túto chybu?

Mne by sa predsa len hodilo keby som mohol aj v POT súbere nadefinovať nejaké parametre, lebo neviem ako to inak urobiť…

voda
Člen | 561
+
0
-

A v jakém jazyce máš výchozí texty v aplikaci? Já je mám anglicky a pak dělám český překlad, takže .pot soubor je čistě ascii.

Postup mám v podstatě stejný, akorát u bodu 3 pro aktualizaci používám příkaz msgmerge -Uv cs.po template.pot a pro překlady pak Lokalize, ale měl by fungovat jakýkoliv nástroj.

Pokud opravdu chceš mít v .pot souboru nastaven charset, napadají mě dvě možnosti:

  1. sed -i 's/charset=CHARSET/charset=UTF-8/' template.pot
  2. uprav výchozí hodnotu https://github.com/…xtractor.php#L60, buď poděděním a upravením gettext-extractor.php aby načítal ten tvůj nebo to přímo uprav v GettextExtractor.php

Editoval voda (6. 10. 2011 11:07)

gawan
Člen | 110
+
0
-

Problém je, že ja mám v kóde SK texty a potrebujem ich preložiť do CZ.

Dobre, skúsim jednu z týchto možností.

voda
Člen | 561
+
0
-

Ještě se může do gettext-extractor.php přidat přepínač na nastavení hlaviček. Jestli se ti chce, můžeš udělat patch a poslat pull request, nebo si chvilku počkat až to tam přidám.

gawan
Člen | 110
+
0
-

neviete niekto, existuje nejaký použiteľný web-base editor pre po, pot súbory, ktorý by som si hodil na svoj hosting a mohol posielať linku svojim prekladateľom? nejako sa mi niečo také nedarí nájsť…

voda
Člen | 561
+
0
-

zkus Pootle

voda
Člen | 561
+
0
-

@gawan: přidal jsem přepínač -m, takže teď můžeš použít ./gettext-extractor.php -m'Content-Type:text/plain; charset=UTF-8' ...

gawan
Člen | 110
+
0
-

super dík, funguje to. Už som to vyriešil prepísaním $meta v triede GettextExtractor, ale s tým prepínačom je to univerzálnejšie riešenie. Inak to pootle sa mi zdá nejaké komplikované, a je to v pythone a to asi nerozchodím na hostingu, možno skúsim urobiť jednoduchý nette-poedit, ak budem mať čas :)

iguana007
Člen | 970
+
0
-

Proč vynalézat kolo? :)

http://code.google.com/p/simplepo/

gawan
Člen | 110
+
0
-

@iguana007 dík to som si nevšimol, idem to pozrieť, či mi to vyhovuje…
nefunguje to, pozerám, že už takmer 2 roky sa to nevyvíja.

Editoval gawan (7. 10. 2011 10:31)

iguana007
Člen | 970
+
0
-

já to ještě nezkoušel, včera jsem hledal nějaké hotové řešení na editaci po souboru a narazil jsem na todle.

Ostatně to samé řeší i translator od Vrtak-CZ via debug panel ( https://github.com/…Localization ), ale budu muset udělat i řešení na samostatné stránce, tak by bylo možná lepší přiohnout to Vrtákovo řešení, než bastlit něco mimo, protože ten jeho panel funguje jak má.

gawan
Člen | 110
+
0
-

ja tiež potrebujem samostatné riešenie, ktoré by bolo nezávislé na projekte, lebo spolupracujem s externými prekladateľmi. Tak keď niečo budeš mať tak daj vedieť.

gawan
Člen | 110
+
0
-

Ako prekladáte dlhé texty v po (pot) súboroch? Ja to robím takto:

  1. v kóde používam napr. jazyk EN a pre dlhé texty mám v kóde skratky napr. __('{manual}')
  2. potom si vytiahnem preklady do locale.pot
  3. vygenerujem prvotný preklad pomocou msginit pre jazyk EN napr: locale.en.po
  4. locale.en.po preložím (teda vlastne prepíšem) IDčka ako {manual} na dlhé texty

Problém ale vzniká, keď vytvorím preklad z pôvodného locale.pot súboru pre druhý jazyk napr: locale.de.po, lebo potom v tomto súbore nie sú dlhé texty ale len ich IDčka {manual}. Takže, toto nemôžem poslať prekladateľke lebo nemá ako preložiť dlhé texty.

Existuje nejaký doporučený postup ako toto robiť? Napr. dá sa vygenerovať po súbor pre druhý jazyk už prekladu iného jazyka (niečo ako locale.en.po → locale.de.po)? Ďakujem za tipy.

gawan
Člen | 110
+
0
-

nikoho nič nenapadá, ako by sa dali prekladať dlhé reťazce?

voda
Člen | 561
+
0
-

@gawan: Máš nějaký důvod nemít i dlouhé texty normálně ve zdrojáku? Co považuješ za dlouhý text? Já tam mám klidně celý odstavec a nemám s tím problém.

gawan
Člen | 110
+
0
-

napríklad: cenník (niekoľko strán textu, všetkých možných služieb, produktov – je to jeden dlhý text na jednej stránke), vzory emailov (napr: odoslaný registračný mail, mail o ukončení platnosti služby, … atď.), všeobecno obchodné podmienky (niekoľko stranový právnický blábol). To naozaj takéto dlhé texty máš priamo v kóde? Nie je to neprehľadné?

Editoval gawan (17. 10. 2011 9:30)

voda
Člen | 561
+
0
-

Tak až takhle dlouhé texty nemám, nejvíc mám třeba několik odstavců. Ale vždy mám označený každý odstavec jednotlivě. Tyhle texty stejně patří do šablony a tam mi to nepřehledné nepřijde.

gawan
Člen | 110
+
0
-

a ako sa dá preložiť celá šablona ako jeden reťazec? Pokiaľ viem, tak môžem prekladať len jednotlivé vety v rámci šablony cez latte marka {_'…'} atď.

Ja to mám zatiaľ tiež tak, že každý takýto dlhý text mám ako samostatný súbor, ktorý inkludujem tam, kde potrebujem a mám ho napísaný v texy. Dá sa nejako povedať tomu extractoru, aby zobral celý súbor napr: registration-mail.texy (prípadne každý súbor *.texy) a použil jeho obsah ako kľúč pre reťazec? Dá sa to nejako?

Editoval gawan (17. 10. 2011 9:30)

voda
Člen | 561
+
0
-

Měl jsem na mysli toto:

default.latte

{block content}
<p>{_'Lorem ipsum … fringilla iaculis.'}</p>
<p>{_'Praesent imperdiet, … posuere quam.'}</p>

zobral celý súbor napr: registration-mail.texy

Přímo to neumí, ale můžeš si napsat vlastní filtr a nastavit ho pro příponu .texy

iguana007
Člen | 970
+
0
-

Dlouhé texty by si měl mít imho v databázi a ne v šabloně … už vidím nadšení klienta, co ti musí volat kvůli každé změně ceníku … není lepší, když si ceník může klient sám kdykoli upravit v administraci?

Patrik Votoček
Člen | 2221
+
0
-

Záleží na tom jestli je ten dlouhý text I18n nebo L18n. V prvním případě to patří do DB (nebo jiného úložiště dynamických dat) a ve druhém bych použil klasicky {_"Lorem ipsum dolor sit..."}.

hapi
Člen | 35
+
0
-

Měl bych dotaz. V @layout.latte mám toto
<title>{ifset $title}{$title} | {/ifset}{_'Administration'}</title> a v default.latte pak {var $title = 'Login'}

Jak proměnnou lokalizovat?

iguana007
Člen | 970
+
0
-

Někde zaznělo něco na způsob:

{var $foo = $template->translate("Bar")}

… ale nezkoušel jsem to

Editoval iguana007 (12. 9. 2012 21:18)

voda
Člen | 561
+
0
-

Nebo lze použít

{capture $title}{_'Login'}{/capure}
doublemcz
Člen | 15
+
0
-

Ahoj,

jak naformátovat do gettextu htmlníže? První problém je, že potřebuju přeložit n:href. A pak je důležitý udržet kontext a obsah tagu A nedělat vlastním gettextem.

Ukázky prací najdete v <a n:href="Reference:" title="Naše reference">referencích</a>
  • Možná změna title v jiném jazyce

Editoval doublemcz (19. 5. 2013 16:07)