Diskuze: Překládání webů

PHP PHP Překládání webů American English version English version

Aktivity (1)
Avatar
Matěj Strnad:25. června 19:03

Jak se dělá překlad webů to se zasahuje do zdrojáku nebo je na to nějaký soubor který to nahrazuje? Jak to řeší např. Google. Protože kdyby zasahovalo do zdrojáku tak by to bylo neefektifní protože např. příjdu na web google.cz a mohu si zvolit z cca. z 50 jazyků, a kdyby se zasahovalo do zdrojáku tak by to znamenalo že tam je cca. 50 zdrojových kódů a když se udělá nějaká změna tak se musí udělat ve všech kódech a to sorry to je nemožný. Omlouvám se za tolik teoretiky. :) ( A ano, Google nepoužívá PHP ale asi to bude podobné :) )

Odpovědět 25. června 19:03
Ty vaše internety!
Avatar
David Hynek
Redaktor
Avatar
David Hynek:25. června 19:09

kdyz s tim dopredu pocitas, mas misto textu jen pozici v poli. pak jen v uvodu staci nasmerovat na spravne pole a je to.

Nahoru Odpovědět 25. června 19:09
Čím víc vím, tím víc věcí nevím.
Avatar
Matěj Strnad:25. června 19:10

No, super tak to mohu programovat od znova co?

Nahoru Odpovědět 25. června 19:10
Ty vaše internety!
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na David Hynek
Petr Čech:25. června 19:42

"pozice v poli" mi nepřipadá jako moc dobrý popis.
Prakticky se to většinou dělá tak, že máš soubory s překlady, pro každý jazyk jeden. To jsou potom nějaké key-value formáty - často se používá JSON, yml, ini, v ČR někdy neon (z Nette) - takové formáty se potom jednoznačně přeloží na asociativní pole a ty se na jednotlivé texty odkazuješ jako indexy pole. Rozhodně ale není dobrý nápad předávat si přímo pole, jinak to nemusí dopadnout dobře.
Spíš se udělá nějaká třída Translator, kterou si přes DI předáš kamkoliv ji potřebuješ. Není dobrý nápad dělat to statické nebo singleton pro ulehčení, poměrně snadno se můžeš dostat do situace, kdy máš na stránce víc jazyků.
Příklad:

cs.json:

{
  "page_title":"titulek",
  "results_count":"nalezeno %d výsledků"
}

en.json

{
  "page_title":"title",
  "results_count":"found %d results"
}

translator.php

<?php

class Translator{
    private $dictionary;

    public function __construct(string $language)
    {
        $this->dictionary = json_decode(__DIR__ . '/lang/$language.json');
    }

    public function translate($key){
        if(isset($this->dictionary[$key])){
            return $this->dictionary[$key];
        } else {
            throw new TranslateException("$key is not translated");
        }
    }
}

kdekoliv jinde:

$translator->translate("results_count",42);

Pozor! Formátovací řetězce nesmí být od uživatele, ale musí je někde pevně definovat programátor, jinak může teoreticky dojít k buffer overflow. Buffer overflow útok je extrémně nebezpečný a může v extrémních případech dovolit ovládnutí celého serveru.

Nahoru Odpovědět  +8 25. června 19:42
the cake is a lie
Avatar
Odpovídá na Matěj Strnad
Uživatel sítě :25. června 19:42

No super, ale vo vo vo tom to je, pořád se učíš.. :)

Nahoru Odpovědět  +1 25. června 19:42
Chybami se člověk učí, běžte se učit jinam!
Avatar
Odpovídá na Petr Čech
Matěj Strnad:26. června 7:05

Šlo by to udělat i do

array()

?

Nahoru Odpovědět 26. června 7:05
Ty vaše internety!
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Matěj Strnad
Petr Čech:26. června 9:50

Můžeš si to udělat jak chceš, jen jsem tě chtěl nasměrovat. Pokud sis to spustit a zjistil jsi, že máš v translator::$dictionary StdClass a ne pole, věz, že to má být

json_decode(__DIR__ . "/lang/$language.json",true);

Ten JSON je vlastně reprezentace pole, jen v jiném formátu. Výhoda je, že JSON (, yml, ini, ...) je velmi rozšířený a každý ho umí číst. Také je to stylisticky lepší, protože překlady jsou typicky "assets" - neměly by obsahovat kód, a proto se neukládají v PHP, ale v něčem, co nejde spustit - proto máš už z principu fungování translatoru čistý překlad bez špagetového kódu.


Vedle JSON nebo jiných formátů lze také ukládat do PHP polí, a to tímto stylem:
cs.php

<?php
return [ // return na úrovni souboru, pole bude vráceno jako návratová hodnota při require()
  "page_title" => "titulek stránky"
];

translator.php:

...
$this->dictionary = require(__DIR__."/lang/$language.php");
...

Já osobně bych toto nepoužíval, protože to bude svádět ke cpaní kódu to překladů, a tam kód nemá co dělat.

Nahoru Odpovědět  +1 26. června 9:50
the cake is a lie
Avatar
Odpovídá na Petr Čech
Erik Šťastný:26. června 10:05

Taky bych ještě dodal, že důvod překladů v oddělených souborech je taky ten, že často pošleš jednoduchý soubor někomu, kdo se živí překladem a on ti pošle zpátky soubor s překlady. On od tebe nechce žádný kód a ty mu taky nechceš posílat žádný kód.

 
Nahoru Odpovědět  +5 26. června 10:05
Avatar
Odpovídá na Petr Čech
Matěj Strnad:26. června 13:45
Fatal error: Uncaught Error: Call to a member function translate()
:(
Nahoru Odpovědět 26. června 13:45
Ty vaše internety!
Avatar
David Hynek
Redaktor
Avatar
Odpovídá na Matěj Strnad
David Hynek:26. června 13:53

:) ta funkce musí existovat, abys ji mohl použít. To co tam kolega vložil byl jen příklad... proto jsem byl se svou odpovědí stručný :)

Nahoru Odpovědět 26. června 13:53
Čím víc vím, tím víc věcí nevím.
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Matěj Strnad
Petr Čech:26. června 14:35

Přímo to, co jsem ukázal já bych asi nechtěl používat, to byl spíš příklad, ani jsem se to neobtěžoval otestovat. Není to žádná věda, nic speciálního. Je to jako každá jiná PHP třída. To, že se to jmenuje Translator je proto, že jsem si to usmyslel, PHP samotné nic takového nedefinuje.
Ty ten svůj vyhledávač (nebo co že to děláš) používáš jako projekt na učení, proto ti vřele doporučím napsat si vlastní řešení, je to celkem fajn cvičení - můžeš si třeba vymyslet sofistikovanosti jako třeba že mezera v klíči značí zanoření atd.

Jen tě chci odradit od 2 nedokonalých praktik, ke kterým tě bude zrovna tohle neuvěřitelně svádět - nedělej to určitě statické, ani to nedělej globální. To znamená, že si to jednou vytvoříš a potom si tu instanci budeš muset předávat všude, kde ji potřebuješ - na tom se naučíš DI (dependency injection) - a také to otestuje, jak dobrý máš objektový návrh, protože u špatného návrhu to většinou spektakulárně ztroskotá a zjistíš, že musíš velkou část projektu přepsat - právě pokud třeba příliš používáš statiku.

Editováno 26. června 14:37
Nahoru Odpovědět  +1 26. června 14:35
the cake is a lie
Avatar
Matěj Strnad:28. června 20:52

Ok o prázdninách až bude nějaký čas tak se na to kouknu ;)

Nahoru Odpovědět  +1 28. června 20:52
Ty vaše internety!
Avatar
Matěj Strnad:29. června 21:06

Mohu to udělat v

.txt

? (ano čtete správně .txt!)
:-P

Nahoru Odpovědět 29. června 21:06
Ty vaše internety!
Avatar
Odpovídá na Matěj Strnad
Matěj Strnad:29. června 21:45

Takto by to cca vypadalo:

title:titulek;
url:URL adresa webu;
:)
Editováno 29. června 21:47
Nahoru Odpovědět  +1 29. června 21:45
Ty vaše internety!
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Matěj Strnad
Petr Čech:29. června 22:10

Můžeš si to dělat jak chceš, klidě se to čti z obrázku... ty formáty, co jsem uvedl se používají proto, že jsou rozšířené a existují nástroje, jak s nimi pohodlně pracovat.

Nahoru Odpovědět  +3 29. června 22:10
the cake is a lie
Avatar
David Hynek
Redaktor
Avatar
Odpovídá na Matěj Strnad
David Hynek:29. června 22:33

skvele, a pak pri kazdem spusteni, budes prochazet soubor, hledat radky s odpovidqjicim textem a napasovavat jej do stranky. To bude mit server velkou radost...

Nahoru Odpovědět  +2 29. června 22:33
Čím víc vím, tím víc věcí nevím.
Avatar
Matěj Strnad:30. června 7:07

Bude XML lepší než TXT?

Nahoru Odpovědět 30. června 7:07
Ty vaše internety!
Avatar
Odpovídá na Matěj Strnad
Martin Štěpánek :30. června 11:09

Určitě, ale vážně doporučuji použít třeba ten JSON ;-)

Nahoru Odpovědět 30. června 11:09
Nesnáším, když někdo u if nepoužívá {}, byť se jedná o jeden řádek.
Avatar
Odpovídá na Martin Štěpánek
Matěj Strnad:30. června 13:54

ale JSON neumím pracovat tak dobře jako s XML nebo TXT :)

Nahoru Odpovědět 30. června 13:54
Ty vaše internety!
Avatar
Odpovídá na Matěj Strnad
Martin Štěpánek :30. června 14:06

Od toho to je, naučíš se to ;)
Nemluvě o tom, že to jsou doslova dvě funkce json_decode a json_encode

Nahoru Odpovědět  +4 30. června 14:06
Nesnáším, když někdo u if nepoužívá {}, byť se jedná o jeden řádek.
Avatar
Matěj Strnad:5. července 10:56

Už to je hotové:

<?php
 // překladač
function tranlate_start(){
$lang = $_COOKIE{'lang'};
if($lang == null){


$lang1 = preg_match('/(.*?)-/ims', $_SERVER{'HTTP_ACCEPT_LANGUAGE'}, $matches) ? $matches[1] : null;
if($lang1 == null){
$lang = $_SERVER{'HTTP_ACCEPT_LANGUAGE'};
}
else{
$lang = $lang1;
}
}
else{
$lang = $_COOKIE{'lang'};
}
if($lang == "cs"){
$data = file_get_contents("./lang/cs.xml");
}
else{
$data = file_get_contents("./lang/en.xml");
}
$data_translate = $data;
return $data_translate;

}


function translate($key, $value, $data){
$key2 = preg_match('/<' . $key . '[^>]*>(.*?)<\/' . $key . '>/ims', $data, $matches) ? $matches[1] : null;
$key2 = str_replace('%value%', $value, $key2);
if($key2 == null){
$key3 = $key;
}
else{
$key3 = $key2;
}
$key_translate = $key3;
return $key_translate;
}
//Načtení jazyka
$data = tranlate_start();
//Překlad
echo translate("hello", "Matěj", $data);
?>

cs.xml:

<?xml version="1.0" encoding="utf-8"?>
<cs>
<hello>Ahoj: %value%</hello>


</cs>

P.S: toto je můj první kód kde používám funkce :D

Nahoru Odpovědět 5. července 10:56
Ty vaše internety!
Avatar
Dan Bulant
Člen
Avatar
Dan Bulant:16. července 10:59

JSON je nejvice efektivni, jelikoz se snadno a rychle da prelozit do array (map a podobne) i v ostatnich jazycich bez velkych znalosti. Tez spousta NoSQL pouziva JSON.

<?
$jazyk = $_SESSION['jazyk'];
$lang = json_decode(file_get_contents('lang.json'));
 ?>
<html>..<p><? $lang[$jazyk]['helllo']; ?></p></html>

pak v json udelat

{
"cz" {
"hello": "ahoj"
}
}
Nahoru Odpovědět  +1 16. července 10:59
Kolik umíš funkcí, tolikrát jsi člověkem.
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:17. července 9:46

To pole bych resil jako strukturu id soubor - id text - text prekladu. Ten json by mohl byt fajn. Ale dal by se pouzit i csv soubor, ktery muzes editovat jak v txt editoru, tak i v excelu.

Google prekladac stranek to muze resit pres parser. Oddeli si text a html kod a text prepise. Neco, jak jsou javascriptove obarvovace html kodu.
Ale, z hlediska prekladu je lepsi jej nechat udelat odbornikovi.

 
Nahoru Odpovědět 17. července 9:46
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Peter Mlich
Petr Čech:18. července 0:26

Hm, csv bych se asi vyhnul, zase asi nechceš, aby si to mohl otevřít každý, kdo má MS Office, ten překladatel by měl vědět, co dělá.

Nahoru Odpovědět 18. července 0:26
the cake is a lie
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:18. července 6:26

Kazdy, mel snadne, ale, to je zamer. Pokud bych tam mel chyby nebo mel nekdo potreby udelat si vlastni preklad, aby mu stacil textovy editor. Podobne jako konfiguracni souboru v linuxu.

 
Nahoru Odpovědět 18. července 6:26
Avatar
Petr Čech
Redaktor
Avatar
Odpovídá na Peter Mlich
Petr Čech:18. července 10:52

Ale to samé platí pro JSON. A stejně tak u té linux konfigurace musíš vědět poměrně dost přesně, co že to děláš.

Nahoru Odpovědět 18. července 10:52
the cake is a lie
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 26 zpráv z 26.