Diskuze: Překládání webů
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 26 zpráv z 26.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
kdyz s tim dopredu pocitas, mas misto textu jen pozici v poli. pak jen v uvodu staci nasmerovat na spravne pole a je to.
No, super tak to mohu programovat od znova co?
"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.
No super, ale vo vo vo tom to je, pořád se učíš..
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.
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.
Fatal error: Uncaught Error: Call to a member function translate()
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ý
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.
Ok o prázdninách až bude nějaký čas tak se na to kouknu
Mohu to udělat v
.txt
? (ano čtete správně .txt!)
Takto by to cca vypadalo:
title:titulek;
url:URL adresa webu;
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.
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...
Bude XML lepší než TXT?
Určitě, ale vážně doporučuji použít třeba ten JSON
ale JSON neumím pracovat tak dobře jako s XML nebo TXT
Od toho to je, naučíš se to
Nemluvě o tom, že to jsou doslova dvě funkce json_decode a json_encode
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
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"
}
}
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.
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á.
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.
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áš.
Zobrazeno 26 zpráv z 26.