Diskuze: PHP&PDO Slovník pro překlad části webu
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 13 zpráv z 13.
//= 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.
Ahoj, když pominu, že jsou jistě lepší metody jak toho docílit...ale
berme to tak, že si procvičuješ, takže ke tvému snažení, by to chtělo
asi jedním dotazem do DB vytáhnout všechny relevantní informace tj. např.
var a cz sloupce pro daný formulář/stránku a z těch si poskládat
asociativní pole, kde var bude klíč a cz bude hodnota... pak můžeš
použít něco takového, co máš v kódu a mělo by to fungovat
asi nebudeš vůbec potřebovat sloupec id, jelikož var by měl být patrně
označen jako unikátní string...
případně přidat nějaký další kontextový sloupec...tzn., že některé
překlady se týkají jen určité části webu, např. přihlašovacího
formuláře.. důvodem je to, abys nenačítal vždy všechny
Ahoj, viděl bych to spíše tak, že budeš mít tabulky:
table_text:
id INT AUTO_INCREMENT PRIMARY KEY,
var VARCHAR,
page VARCHAR DEFAULT NULL
table_language:
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR,
acronym VARCHAR
table_text_language:
id INT AUTO_INCREMENT PRIMARY KEY,
text_id INT,
language_id INT,
content TEXT
Kdy sloupec page
bude obsahovat název stránky. Když bude
NULL, bude to nějaký obecný text (třeba text do hlavičky, patičky, nebo
něco, co se vyskytuje často - taková ta obecná slova jako "ano", "ne"
atd.).
V tabulce language
budeš mít jednotlivé jazyky (cz, sk, en,
...), kterou si můžeš libovolně rozšířit (např. si dát sloupec, který
určuje, zda je daný jazyk na webu povolen).
Pomocí tabulky text_language
pak "propojíš" jeden text s více
jazyky (sloupec content
obsahuje konkrétní text pro konkrétní
jazyk).
Do PHP pole to pak můžeš nacpat například takto:
$page = $_GET["page"]; // např. index.php?page=homepage -> $page = homepage
$language = $_GET["language"]; // např. index.php?page=homepage&language=cs -> $language = cs
$textsQuery = $pdo->prepare("
SELECT * FROM `table_text_language`
INNER JOIN `table_language` ON `table_text`.`language_id` = `table_language`.`id`
INNER JOIN `table_text` ON `table_text_language`.`text_id` = `table_text`.`id`
WHERE `table_language`.`name` = ? AND (`table_text`.`page` = ? OR `table_text`.`page` IS NULL)
");
$textsQuery->execute(array($language, $page));
$textsData = $textsQuery->fetchAll();
$translations = array();
foreach ($textsData as $textData) {
$translations[$textData["var"]] = $textData["content"];
}
Pokud bys chtěl předejít případným chybám, že daný text podle 'var' v databázi není, můžeš si udělat jednoduchou funkci
function getText($name, $default = NULL)
{
global $translations; // pro ukázku neřešme, že global je fuj
if (isset($translations[$name])) {
return $translations[$name];
}
// pokud neexistuje daný text, vrátí se něco výchozího
if ($default !== NULL) {
return $default;
}
// pokud není zadáno nic výchozího, vrátí se třeba "název" toho textu
return $name;
}
// použít to pak můžeš jednoduše
<div>
<?php echo getText("todayDateIs"); ?> <?php echo date("d.m.Y"); ?> // vypíše např. "Dnešní datum je 8.4.2019"
</div>
Ahoj, jestli tomu dobře rozumím, tak máš někde v menu jazykovou mutaci pouze CZ a EN a nechceš měnit celý obsah. Pak bych na to šel asi jinak. V případě češtiny bych nechal stránce normální běh a pouze při volbě EN bych spustil session. Při kliku z EN na CZ bych zas session ukončil. Pak jednoduchá podmínka jestli je session spuštěná nebo ne a podle toho vypsat hodnotu z pole. Pokud těch dynamických prvků nebude příliš a neuvažuješ o rozšiřitelnosti, tak mi to přijde jako nejrychlejší způsob a databázi vůbec nepotřebuješ.
Taky bych mel reseni. Podobne M. Konečný. Myslim si, ze odolne vuci
chybam.
tab. stranky - page_id, name, content
tab. jazyky - lang_id, name
tab. prekladu - transl_id, name, translate
tab. propojovaci - lang_id, page_id, transl_id
nebo bez tab jazyky:
tab. prekladu - transl_id, page_id, name, translate_cz, translate_en
Nebo nejak jinak
Potrebujes, aby sql dotaz vratil pro konkretni stranku konkretni name
konkretni text. V podstate by misto name v posledni tabulce slo pouzit
transl_id. transl_id by se nemelo na strance opakovat. (Vim, spousta lidi ma
predstavu, ze vyuzije slovnik univerzalne, ale to je obecne spatne reseni. Pokud
ovsem nemas ve slovniku vsechny mozne tvary.)
A potrebujes tim dotazem vratit vsechny preklady podle page_id, abys nemusel
dotaz volat vicekrat. Ty ulozis do pole, jak psal T. Novotný.
translate_cz or translate_en or name
Name zadavas v php. Pokud neexistuje cesky preklad, melo by to vratit anglicky.
Pokud ani ten nebo nastane jina chyba, melo by to vratit aspon name. Pokud by to
vratilo prazdne policko, je to chyba, neklikatelny odkaz a pod. Viz tez M.
Konečný.
<a href=123></a>
<a href=123>titleOne</a>
Ale ja bych jeho podminky rozsiril, pokud text je null nebo trim(text), ktery ma jit do returnu je '' (prazdny) , tak by mel vratit name. Muze se stat, ze v tom poli (T. Novotný) proste ta hodnota je undefined, null nebo '' a nebo mezera, tabelator, novy radek, proto trim.
Pokud bych měl navrhnout řešení lokalizace, tak bych využil spíše než
DB tak GetTextu a *.mo, *.po a *.pot souborů. Už jeho samotné použití
řeší některé zde zmíněné jazykové fallbacky, pokud překlad v daném
jazyce neexistuje.. Navíc přidává možnosti do lokalizovaného textu
jednoduše vkládat i proměnné. Tento způsob se používá v různých
obdobách a jazykový implementacích bez mála 30 let.
více třeba tu https://cs.wikipedia.org/…/GNU_gettext
počáteční nastudování by se mohlo zdát pro někoho obtížnější, ale
přínos dle mne jistě vyváží časovou investici a to i pro menší
projekty
reálné použití lze omrknout u většiny opensource CMS
další zajímavý plus vidím v tom, že případnou lokalizaci do
exotického jazyka (většinou z en) zvládne díky šabloně *.pot a např.
programu PoEdit běžný uživatel PC
přidáš něco na web tj. zaktualizuješ soubor šablony s texty a můžeš ho
předat překladatelům, kteří mohou udělat i nějaké revize stávajícího.
Myslím, že je tam implementováno i něco jako max. délka překladu - tj. aby
ti to nerozbilo layout pro různé mutace. Také jsou tam možnosti pro
použití množného/jednotného čísla, pokud existují rozdílné tvary pro
jednotlivé jazyky.
Tomáši, díky za zmínění getTextu. Naposledy jsem o něm četl před mnoha lety a to v souvislosti s C++. Je dobré vědět, že se stále používá. Potenciál využití je celkem široký i na dnešní dobu.
Díky všem. Nakonec jsem zkusil jít cestou gettextu, ale narazil jsem na problém při nasazování u Wedosu s tím, že nepodporuje putenv. Přitom gettext podporuje.
putenv('LANG=' . $language);
setlocale(LC_ALL, $language);
// Set the text domain as 'messages'
$domain = "messages";
bindtextdomain($domain, "Locale");
textdomain($domain);
Jde to nějak obejít?
Patrně nemáš přístup ke změnám proměnné LANG v prostředí
webhostingu... na druhou stranu úplně netuším, k čemu to potřebuješ
nastavovat... třeba php manuál uvádí v příkladu jinou implementaci
gettextu než si poslal...
https://www.php.net/….gettext.php
Ah táák, měl jsem za to, že nemáš přístup jen k některým nastavením. Nemyslel jsem si, že by zakázali celou funkci... ale když tak koukám do phpinfo.... tak to je na konzultaci s hostingovou podporou, co je k tomu vede.
Tak z podpory mi zatím odpověděli, že mám ten řádek s putenv zakomentovat...
Jde to rozchodit i bez použití funkce putenv? Návodů k gettextu je na internetu fakt minimum, ale přijde mi to jako hodně elgantní řešení, tak bych to nechtěl vzdát. Měnit hosting kvůli tomu ale nebudu...
Zobrazeno 13 zpráv z 13.