Překlad frontendu ve Vue

hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Překlad frontendu ve Vue
« kdy: 28. 11. 2024, 09:46:47 »
Mam FE napisany vo Vue a riesim aktualne preklad. Mam svoj vlastny system ktory riesi preklad, ale v principe je velmi podobny Vue i18n, akurat ze taha data cez api z backendu namiesto velkeho jsonu.

Co je ale univerzalny problem je preklad blokov textu, alebo ak text obsahuje komponenty.

Uz len taka blbost ako:

Kód: [Vybrat]
<p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>
Robi problem, kedze obsahuje dynamicky komponent. Na vyriesenie by som musel routu predgenerovat a dodat ako string, alebo natvrdo zaclenit do prekladu ako relativnu cestu. Co je v pohode, pokial sa neriesia parametre(napriklad id aktualneho uzivatela). Samozrejme to znemozni jednoducho zmenit cestu pre rotuy bez naslednej aktualizacie vsetkych prekladov ktore maju cestu natvrdo v sebe. V praxi teda nepouzitelne a musel by som robit string formating nahradzanim obsahu v stringoch dynamickymi argumentmi(co je ok a bezna prax).

Dalej su tu bloky textu kedy nie len ze mozu obsahovat dalsie komponenty, ako priklad hore, ale aj html(popravde aj priklad hore), takze renderovanie prekladu musi byt riesene cez v-html, lenze tam je zase problem ze rodic nie vzdy musi byt div, takze preto element musi byt konfigurovatelny. Pripadne sa to da riesit cez vue direktivu ale v principe je to jedno, lebo preklad samotny musi obsahovat html, co je niekedy ok ale inokedy zase to html moze byt renderovane komponentou, ktora aj casto bude mat nejake atributy a to je nemozne riesit v tomto kontexte.

Napriklad:

Kód: [Vybrat]
<div>
  <p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>
  <FooComponent class="foo bar car" :some="'value'" :and="5" :current-user="getUid()" />
  <p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>
</div>

Pretoze je jedna vec spravit string formating/replacement ak ide o nahradu "foo %" na "foo 5", ale riesit komponenty skratka mozne nie je, kedze su to dynamicke objekty ktore vratia dynamicke(eventy, reaktory..) html az ked ich Vue vyrenderuje. Cize toto je absolutne neschodne riesenie.

Je mozne velke bloky rozkuskovat na jednotlive vety a to sa da ale zase mi pride ze to je take skriabanie sa lavou rukou za pravym uchom, ako sa hovori.

Takze zatial som nejak neni spokojny so ziadnym riesenim a zaujima ma, ze ako ludia riesia tento problem v praxi?

Prakticky akykolvek moderny JS framework asi ma totozny problem, React, Vue,.. je to jedno, rovnaky  princip problemu.


Re:Ako na preklad Vue frontendu?
« Odpověď #1 kdy: 28. 11. 2024, 11:42:26 »
S žádnými JS frameworky sice nedělám, ale překladům různých systémů a aplikací se věnuji už hodně dlouho a funguje to asi takto:

  • delší texty se kouskují do vět běžně
  • do textu k překladu patří jen to, co se má skutečně přeložit, vše ostatní se nahrazuje tagy a ty se pak injektují pomocí jako parametry v další funkci (sprintf apod.) nebo v překladové funkci (Vue i18n má k tomuto účelu $t).
  • HTML tagy do překládaného textu nepatří vůbec, od toho jsou šablonovací systémy

hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Re:Překlad frontendu ve Vue
« Odpověď #2 kdy: 28. 11. 2024, 16:49:44 »
1. jasne, nie je problem.
2. to je prave v tychto modernych js frameworkoch nemozne z dovodov ktore som jasne popisal
3. to iste co bod 2

Re:Překlad frontendu ve Vue
« Odpověď #3 kdy: 01. 12. 2024, 09:13:47 »
V Reactu používame https://react.i18next.com/latest/trans-component, předpokládám, že něco na podobném principu bude k dispozici i pro Vue.

BoneFlute

  • *****
  • 1 987
    • Zobrazit profil
Re:Překlad frontendu ve Vue
« Odpověď #4 kdy: 07. 12. 2024, 02:17:31 »
Protože jsem se zamiloval do https://projectfluent.org/, tak já bych to řešil takto:

1/ Text nekouskovat, nemá-li to smysl.
2/ Na formátování použít ořezané html, nebo markdown.
3/ odkazy nebo objekty bych řešil pomocí placeholderu. Takže příklad ze zadání bych řešil takto:

Kód: [Vybrat]
<p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>bych řešil:
Kód: [Vybrat]
Lorem Ipsum <a foo.bar>dolor</a> sit amet.Poznámka: Překladatel potřebuje vědět, co má umístit do odkazu, a kam ten odkaz umístit. Ale nezajímá ho vlastní odkaz, jeho formát ani kam vede.

Kód: [Vybrat]
<div>
  <p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>
  <FooComponent class="foo bar car" :some="'value'" :and="5" :current-user="getUid()" />
  <p>Lorem Ipsum <router-link :to="{name: 'foo.bar}">dolor</router-link> sit amet.</p>
</div>
bych řešil:
Kód: [Vybrat]
  <p>Lorem Ipsum <a foo.bar>dolor</a> sit amet.</p>
  <component foo />
  <p>Lorem Ipsum <a foo.bar>dolor</a> sit amet.</p>

případně markdownem:
Kód: [Vybrat]
  Lorem Ipsum <a foo.bar>dolor</a> sit amet.
 
  <component foo />
 
  Lorem Ipsum <a foo.bar>dolor</a> sit amet.


hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Re:Překlad frontendu ve Vue
« Odpověď #5 kdy: 07. 12. 2024, 03:52:20 »
Na koniec mi prislo ze jedine rozumne riesenie je mat template pre kazdy jazyk a proste robit switch. Pretoze injektovat dynamicke komponenty do prelozitelneho textu je sice niekedy mozne, ale duplom nie ak ma komponent otvaraci a zatvaraci tag, pretoze skor ci neskor sa tym pokasle sklonovanie a vznikol by z toho spagetovy kod.

Takze proste:
Kód: [Vybrat]
<template>
<Czech v-if="lang === 'CS' />
<Slovak v-else-if="lang === 'SK' />
<German v-if="lang === 'DE' />
<English v-else />
</template>

<script>
import Czech from 'components/foo/languages/CZ.vue
...
</script>

Rezat text je mozne len ak ide o kratke slovne spojenia a vety ale nie ak ide o bloky textu napriklad.

Priklonil by som sa skor k tomu aby sa switch dial na urovni routeru ale zda sa, ze to nie je mozne, lebo nie je moze dynamicy prepisat 'component' v route, napriek tomu ze je to funkcia ktora len inkluduje template. Proste treba switchovat priamo vo vue template az.
« Poslední změna: 07. 12. 2024, 03:56:54 od hknmtt »

BoneFlute

  • *****
  • 1 987
    • Zobrazit profil
Re:Překlad frontendu ve Vue
« Odpověď #6 kdy: 07. 12. 2024, 14:14:32 »
...
Jen tak pro zajímavost, a v jaké podobě to dostane překladatel?

BoneFlute

  • *****
  • 1 987
    • Zobrazit profil
Re:Překlad frontendu ve Vue
« Odpověď #7 kdy: 07. 12. 2024, 14:19:27 »
Pokud ti na tom záleží, tak toto
Pretoze injektovat dynamicke komponenty do prelozitelneho textu je sice niekedy mozne, ale duplom nie ak ma komponent otvaraci a zatvaraci tag, pretoze skor ci neskor sa tym pokasle sklonovanie a vznikol by z toho spagetovy kod.
bych ti radil ještě dobře promyslet. IMHO se mýlíš. A je samozřejmě škoda, když na základě chybného předpokladu vybereš neoptimální řešení.

hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Re:Překlad frontendu ve Vue
« Odpověď #8 kdy: 08. 12. 2024, 16:31:33 »
...
Jen tak pro zajímavost, a v jaké podobě to dostane překladatel?

No tak PO subor to uz asi nebude. Prekladat cele templejty tiez nie je idealne riesenie, kedze mozno kvoli par vetam kopirovat cely template je dost neprijemne z mnohych hladisiek. Ale nevidim ine vychodisko momentalne.

Ono je jedna vec ked mam
Kód: [Vybrat]
Hello <a href="@link">world</a>.ako kedysi. Ale dnes mam
Kód: [Vybrat]
Hello <router-link :to={...}>world</router-link> a teda to musi byt interpretovane a nie len jednoducho vyprintovane ako plain text/html.

Dalsi problem je ze nie je mozne len tak rozsekat text a potom len pozliepat vety ako
Kód: [Vybrat]
{{ t('Hello') }} {{ t('world') }} pretoze ked pride na dlhsie vety, tak sa skor ci neskor pokasle sklonovanie. Navyse je hlavnym problemom to, ze ak mam napriklad vetu
Kód: [Vybrat]
Hello <component>world, is it nice</component> today? tak ja potrebujem tomu komponentu dodat prelozeny text, cize v tomto pripade
Kód: [Vybrat]
world, is it nice lenze to skratka nie je nijako mozne kedze ja nemam ako urobit interpetaciu otvaracich a zatvaracich tagov toho komponentu a vyrenderovat to dynamicky a nemozem to rozsekat na 3x t() pretoze tam nema sancu vediet sklonovanie.

Proste poreklady v dynamickych/interpretovanych JS frontendoch je naproste peklo pretoze dnes prakticky dynamicky tvorime templejty ktore musia byt interpretovane nez vypoluju vysledok kdzeto v minulosti sa len printoval primo text bez dynamickych komponentov.
« Poslední změna: 08. 12. 2024, 16:36:49 od hknmtt »

hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Re:Překlad frontendu ve Vue
« Odpověď #9 kdy: 08. 12. 2024, 16:39:29 »
Aj ked viem ze preklady mozu mat kontext, cize rozkuskovat jednu vetu kvoli komponentu na tri a viac casti by teoreticky slo spravit spravne, poskytnutim kontextu. Lenze a) popravde som kontexty nikdy v prekladoch nepouzival a ani ich nemam implementovane vo svojom kode nijako. A za b), aj tak nie je mozne zachovat spravne sklonovanie a vetnu strukturu pri preklade, pretoze natvrdo tak diktujem kde a ako sa ma veta rozdelit, co je proste uplna blbost, kedze kazdy jazyk iny.

BoneFlute

  • *****
  • 1 987
    • Zobrazit profil
Re:Překlad frontendu ve Vue
« Odpověď #10 kdy: 09. 12. 2024, 00:19:59 »
...
Jen tak pro zajímavost, a v jaké podobě to dostane překladatel?

No tak PO subor to uz asi nebude. Prekladat cele templejty tiez nie je idealne riesenie, kedze mozno kvoli par vetam kopirovat cely template je dost neprijemne z mnohych hladisiek. Ale nevidim ine vychodisko momentalne.

Ono je jedna vec ked mam
Kód: [Vybrat]
Hello <a href="@link">world</a>.ako kedysi. Ale dnes mam
Kód: [Vybrat]
Hello <router-link :to={...}>world</router-link> a teda to musi byt interpretovane a nie len jednoducho vyprintovane ako plain text/html.

Tady si asi nerozumíme.

1/ Já bych to rozhodně nerozsekával. Naopak.

2/ Takto:
Kód: [Vybrat]
Hello <a href="@link">world</a>. spíše ne.

Já bych to dělal takto:
Kód: [Vybrat]
Hello <a ref="link">world</a>.
V tom překladovém řetězci je jen to nejnutnější, aby překladatel věděl, že kde ten tag začíná, kde končí, a jak se jmenuje. V žádném případě tam nesmí být žádná složitost.

Takže následně se to přeloží
Kód: [Vybrat]
<a ref="link"> se nahradí za
Kód: [Vybrat]
<router-link :to={...}>.

Analogicky když máš větší komponentu. Komponenta sama o sobě je překládaná separátně. Ledaže by bylo žádoucí nějak zohledňovat kontext. Což se řeší stejným způsobem jako u toho odkazu:

Kód: [Vybrat]
Hello <a ref="link" title="To je odkaz, víme?">world</a>.

Navyse je hlavnym problemom to, ze ak mam napriklad vetu
Kód: [Vybrat]
Hello <component>world, is it nice</component> today? tak ja potrebujem tomu komponentu dodat prelozeny text, cize v tomto pripade
Kód: [Vybrat]
world, is it nice lenze to skratka nie je nijako mozne kedze ja nemam ako urobit interpetaciu otvaracich a zatvaracich tagov toho komponentu a vyrenderovat to dynamicky a nemozem to rozsekat na 3x t() pretoze tam nema sancu vediet sklonovanie.
V čem přesně je ten problém? Mě to přijde celkem přímočaré a nekomplikované.

Mám komponentu ve zdrojáku (pseudokód):
Kód: [Vybrat]
trans = "Hello <component ref="a">world, is it nice</component> today?"
node = translator.translate(trans)
component_a = createComponentA()
component_a.content = node.placeholders['a'].content
node.translate(["a": component_a])

toliko princip. Předpokládám, že každý normální FW to bude mít nějak řešený. Přiznávám, že jak je to řešené ve Vue nevím, ale pokud jsem se ztratil v teorii, a ty si chtěl konkrétní řešení zrovna pro Vue, tak se omlouvám.

Takhle bych to řešil, a pokud to Vua neumí, tak bych si to naimplementoval.


Proste poreklady v dynamickych/interpretovanych JS frontendoch je naproste peklo pretoze dnes prakticky dynamicky tvorime templejty ktore musia byt interpretovane nez vypoluju vysledok kdzeto v minulosti sa len printoval primo text bez dynamickych komponentov.
Pokud se ošklivě nepletu, tak bych ten problém spíše viděl v tom, že se na to autoři vykašlali :-) Jak na to by neměl být problém. Že to není naimplementované, to je možné.

hknmtt

  • ***
  • 164
    • Zobrazit profil
    • E-mail
Re:Překlad frontendu ve Vue
« Odpověď #11 kdy: Dnes v 18:34:57 »
Tak som na to konecne prisiel.

V principe islo o to ze som musel mentalne opustit koncept gettext na ktory som dlhe roky zvyknuty a pochopit ze tieto reaktivne js frameworky pouzivaju catgets. Rozdiel je v tom ze pri gettext je zdrojovy string vlastne samotny text, ako veta alebo slovne spojenie. Pri catgets je to vsak iba kluc v mape/objekte a teda to umoznuje lepsie pracovat s kontextom pretoze pri gettext by som mal napriklad "About" ako kluc ale to moze znamenat viacero veci, ako "o mne", "o nas", "o.." a kedy sa nemusi uvadzat dodatocne upresnenie lebo je jasne z kontextu. Pri catgets mam zase kluc "about_us" alebo "about_me" a teda kontext je sucastou kluca. Respektive, vezmime si "Name" co moze byt nazov niecoho ale aj meno osoby alebo prikaz a podobne, cize slovesa vs podstatne mena a td. Gettext ma sice moznost definovat kotnext ale ten sa v praxi moc nepouziva a teda prakticky ak raz definujem "Foo" tak ma iba jedne vyznam.

V kazdom pripade, catgets z principu umoznuje vytvorit funkcny string slicing kedy sklonovanie v roznych jazykoch nie je problem ak rozdelujeme jednu vetu na dve a viac casti, napriklad ak mame vo vete nejaky dynamicky komponent. Skratka si spravim definiciu foo: {one: "", two: "", three: ""} a potom to len v templejte vyprintujem na spravnom mieste a kazdy jazyk na to moze reagovat po svojom.

Takze tak. V principe teda islo o to pochopit ze string slicing je jedina moznost ako preklady v dynamickych js frontendoch mozu fungovat a ze gettext sa tu nepouziva.