TranslationClient – překlad řetězců přímo na stráce

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

Zdravím všechny,
zhruba po dni kódování a psaní úděsného JavaScriptu se mi povedlo zrealizovat dle mého názoru docela zajímavou myšlenku – nástroj pro překládání přímo na stránce. Abyste si udělali představu, jak to vypadá, tak 2 ukázky:

Před rozbalením:

Po rozbalení:

Hezké, co?

Asi vás napadne, co bude použití takové srandy v projektu obnášet – moc toho není. Stačí přidat zhruba jeden řádek do bootstrap.php

TranslationClient::enable($translator);

… a zajistit, že předávaný $translator bude implementovat následující rozhraní…

interface IEditableTranslator extends ITranslator
{
	public function getVariantsCount();
	public function getStrings();
	public function setTranslation($message, $string);
	public function save();
}

… a to by mělo být vše. Může se překládat.

Nyní se ještě trošku vrátím k tomu rozhraní.

Metoda getVariantsCount() by měla vracet počet tvarů slov podle kvantity v daném jazyce. Pro angličtinu se tedy vrací 2 (singulár, plurál), čeština 3 (singulár, plurál pro 2 – 4, plurál pro 5+).

Metoda getStrings() by měla vracet asociativní pole řetězců, které se zobrazí v klientovi. Pokud řetězec není závislý na počtu, měl by se vrátit jako řetězec. Pokud závislý je, tak by se mělo vrátit pole s tolika prvky, kolik je variant. Názornější asi bude příklad (psáno v JSONu):

{
  "news": "Novinky",
  "categories": [
    "%n kategorie",
    "%n kategorie",
    "%n kategorií"
  ]
}

Tento seznam řetězců samozřejmě nemusí být jen nějaký nadefinovaný seznam, IEditableTranslator si klidně může ukládat bokem „neuspokojené“ překlady a do klienta je naservírovat k překladu – klient totiž tuto metodu volá až při ukončování scriptu (ve stejnou dobu, kdy se renderuje např. profiler), takže se tam může promítnout opravdu vše, co bylo voláno.

Metoda setTranslation($message, $string) nastaví překlad nějakého řetězce. Pro řetězec bez plurálů se opět použije jen string, pro řetězec s plurály pole všech variant.

Mno a metoda save() všechny provedené překlady uloží.

Nastavování jednotlivých překladů probíhá AJAXem. Uživatel v klientovi přeloží jeden či více řetězců a klepne na uložit. Klient provede AJAXový požadavek (identifikovaný speciální hlavičkou, takže se nebude míchat s ostatními požadavky) na URL se současnou stránkou (bez signálů atp.) a během požadavku se jeho data uloží.

Ukládání momentálně probíhá na konci volání TranslationClient::enable(...) a po uložení dat vykonávání scriptu zemře (die()), aby se předešlo případným vedlejším efektům. Toto chování mi nepřipadá úplně ideální a určitě by sneslo nějakou změnu. Také z toho vyplývá jeden možná trochu nepříjemný požadavek – IEditableTranslator už v době volání musí být schopen data bez problémů ukládat.

Na závěr bych chtěl říct, že to celé je zatím spíš ve stádiu experimentu, takže 100% funkčnost a stabilita není garantována. Dokonce to jde tak daleko, že mohu garantovat jedině nefunkčnost snad v jakékoliv verzi IE. Fungovat by to mělo ve FF, Chrome a Opeře + možná v dalších prohlížečích, pro které „moderní standarty“ nejsou jen sprosté slovo.

Na závěr bych chtěl vznést několik námětů na diskuzi, budu rád za jakýkoliv komentář:

  • Chybí vám tam něco? Mělo by to ještě něco zohledňovat?
  • Kam by jste dali zpracování ukládaných dat? A po něm být, či nebýt? continue, či die()?
  • Má smysl podporovat IE6? Je to převážně nástroj pro vývojáře a žádného masochistu, co vyvíjí primárně na IE6, neznám…
  • Má to vůbec smysl?

A teď už samotné zdrojáky, byl bych rád, kdyby si někdo našel chvilku času na prozkoumání a otestování: TranslationClient.zip. Nějakou ukázkovou miniaplikaci včetně translatoru, který bude implementovat IEditableTranslator, dodám snad v průběhu víkendu. Nějakou ukázku toho translatoru vážným zájemcům dodám na požádání.

A ještě si neodpustím malé varování: kód není komentovaný, neobsahuje phpdoc, míst k refaktorování by se tam našlo mnoho… To bude až časem.

Blizzy
Člen | 149
+
0
-

IE6 se v těchto případech podporovat rozhodně nevyplatí, i když IE8 by to asi podporovat mělo.

Myslím, že je to zajímavý nástroj a určitě se najdou tací, kterým se to bude hodit.

Panda
Člen | 569
+
0
-

S IE8 počítám, jen dneska už nemám sílu hledat, co mu vadí.

norbe
Backer | 405
+
0
-

No musím říct, že to vypadá fakt dobře a rozhodně si dokážu představit, že by to mohlo nahradit nástroje jako poedit, u kterých je problém se získáváním všech řetězců.

  • IE6 podporovat je podle mýho naprosto zbytečný.
  • die() bych asi nepoužíval, to si může nastavit každý podle svého přímo v metodě save(), ne? A když už tak bych volal spíš $presenter->terminate().
Panda
Člen | 569
+
0
-

Presenter v bootstrap.php ještě není k dispozici, čím se dostáváme otázce: kde nejlépe provést zpracování požadavku tak, aby dopad na zbytek aplikace byl co nejmenší? Teď mě napadl event Application::onRequest, ale ten se taky volá těsně před vytvořením presenteru…

die() bych do save() rozhodně netahal, nemusí se volat jen v tomto konkrétním případě…

ic
Člen | 430
+
0
-

Vypadá to velmi působivě… hned se na to podívám.

Honza Kuchař
Člen | 1662
+
0
-

Vypadá to suprově!

P.S.: Ad. die() a kód ještě před spuštění Presenteru. MultipleFileUpload funguje se zpracováváním svých požadavků dost podobně. V Application::onStartup si zaregistruje co se má dělat a pak volá exit.

Editoval honzakuchar (19. 2. 2010 19:12)

Honza Kuchař
Člen | 1662
+
0
-

P.P.S.: Přidáš to do extras?

Panda
Člen | 569
+
0
-

honzakuchar napsal(a):

P.P.S.: Přidáš to do extras?

Až to bude více odladěné, tak určitě.

Honza Marek
Člen | 1664
+
0
-

Dostal jsem teď takový nápad. Možná by bylo pěkné, kdyby existovalo nějaké oficiální API pro tvoření takových šikovných nástrojů a jejich integrace do nějakého jednotného panelu. Více napoví obrázek.

Jistě by vznikla celá řada zajímavých vývojářských nástrojů. Jen teď mě napadá tlačítko na smazání cache či tlačítko na jednoduché vytvoření presenteru a souvisejících souborů (šablon).

Honza Kuchař
Člen | 1662
+
0
-

@Honza Marek: Perfektní nápad! ;)

Blizzy
Člen | 149
+
0
-

Honza Marek napsal(a):

Jen teď mě napadá tlačítko na smazání cache či tlačítko na jednoduché vytvoření presenteru a souvisejících souborů (šablon).

Nebo debugovací konzole, která doteď vyskakuje v popup okně. :)

Panda
Člen | 569
+
0
-

Honza Marek napsal(a):

Dostal jsem teď takový nápad. Možná by bylo pěkné, kdyby existovalo nějaké oficiální API pro tvoření takových šikovných nástrojů a jejich integrace do nějakého jednotného panelu. Více napoví obrázek.

Jistě by vznikla celá řada zajímavých vývojářských nástrojů. Jen teď mě napadá tlačítko na smazání cache či tlačítko na jednoduché vytvoření presenteru a souvisejících souborů (šablon).

Přesně tento nápad jsem taky v posledních dnech měl, dokonce jsem měl už 2× nutkání to začít realizovat. Váhal jsem převážně nad tím, jestli to postavit na jQuery (snadná varianta), nebo to podobně jako TranslationClient napsat v čistém JS (pomalá a bolestná varianta). Co myslíte?

Honza Marek
Člen | 1664
+
0
-

Já bych byl proti pomalým a bolestným variantám. Zkusil bych to pod jQuery. Jedině pokud by se zjistilo, že z celého frameworku je potřeba jen show a hide, tak bych to přepsal.

Jaké jsou vlastně výhody čistého JS? Natáhnutí frameworku bych jako velký problém neviděl (při nepřítomnosti se stáhne od googlu), s konkurencí se taky jQuery pomocí jQuery.noConflict() umí dohodnout.

iguana007
Člen | 970
+
0
-

tak vše v tomto vlákně je hodně pěkné ;)

ad JS: +1 pro jQuery

buff
Člen | 63
+
0
-

jQuery +1. Rovněž nevidím žádnou výhodu čistého JS.

Ondřej Mirtes
Člen | 1536
+
0
-

Pokud by se to mělo pak implementovat do Nette, tak bych to od jQuery osvobodil. Formuláře ani Laděnka to taky nevyužívá.

Aurielle
Člen | 1281
+
0
-

No já bych zase byl pro jQuery, protože ho používá minimálně AJAX…

redhead
Člen | 1313
+
0
-

ajax ale tady zrovna nepotřebujeme, že? A i kdyby není to pravidlem, že musíme požít zrovna jQuery. Podle mě pro jednoduchý show/hide není potřeba tahat celý jQuery..

norbe
Backer | 405
+
0
-

Byl bych pro panel, který bude postaven na čistém js. Jednotlivé nástroje ať potom využívají co uznají jejich autoři za vhodné. Každý si pak může rozmyslet, jestli si kvůli danému nástroji požadované knihovny naincluduje nebo ne.

Honza Kuchař
Člen | 1662
+
0
-

Upřimě řečeno. Ať si to klidně tahá třeba celý ExtJS. Jen ať to autorovi panelu zabere co nejmíň času. (řači o nějakou tu hodinku déle spát) Stejně je to pro ladění na localhostu. Takže i pokud ten JS bude mít třeba 1MB, tak mě to nijak neohrozí. Takže klidně jQuery + ExtJS + co bude potřeba + klidně ještě něco dalšího. ;) (pokud to ušetří autorovi čas; resp. ušetří určitě, protože jQuery je více méně cross-browser)

despiq
Člen | 320
+
0
-

videl bych to stejne

jasir
Člen | 746
+
0
-

honzakuchar napsal(a):

Upřimě řečeno. Ať si to klidně tahá třeba celý ExtJS. Jen ať to autorovi panelu zabere co nejmíň času. (řači o nějakou tu hodinku déle spát) Stejně je to pro ladění na localhostu. Takže i pokud ten JS bude mít třeba 1MB, tak mě to nijak neohrozí. Takže klidně jQuery + ExtJS + co bude potřeba + klidně ještě něco dalšího. ;) (pokud to ušetří autorovi čas; resp. ušetří určitě, protože jQuery je více méně cross-browser)

Jasný souhlas :-)

pekelnik
Člen | 462
+
0
-

Super nápad. Jsem jednoznačně pro použití jQuery. Psát něco v čistém JS je nesmysl.

Vyki
Člen | 388
+
0
-

Jquery – „write less do more“. A jelikož to platí i naopak, byl by hřích jej nevyužít :o)

Editoval Vyki (14. 3. 2010 22:45)

iguana007
Člen | 970
+
0
-

Panda napsal(a):

bude implementovat následující rozhraní…

ahoj, dostal jsem se k tomu testu až nyní a bouhžel nechápu co myslíš tím: … a zajistit, že předávaný $translator bude implementovat následující rozhraní…
můžeš to prosím nějak upřesnit? Díky moc.