7: Vertalingen
Phlo behandelt vertaling als een renderingskwestie: je schrijft view-tekst in je brontaal, markeert het, en de lang resource levert de juiste taal op het moment van aanvraag, waarbij ontbrekende invoer op de achtergrond wordt vertaald. In dit hoofdstuk leert de poll Nederlands onder een /nl prefix.
7.1: Bron-taal markers
Statische view-tekst krijgt een marker die is gekeyd op de taal waarin de tekst is geschreven. De brontaal van deze app is Engels, dus de sleutel is en:
view:
<main#app.poll>
<h1>{en: Which stack wins?}</h1>
{{ $this->results }}
{{ $this->choices }}
</main>
{en: ...} compileert naar een oproep naar de en() helper, die de vertaallaag vraagt om de tekst in de actieve taal. Als de actieve taal Engels is, gaat de tekst ongewijzigd door. Als je een app met een Nederlandse brontaal zou schrijven, zou je {nl: ...} gebruiken met dezelfde mechanismen; de marker noemt altijd de brontaal van die specifieke string. Buiten views werken dezelfde helpers in code: method title => en('Phlo Poll').
Werk nu de <h1> in poll.phlo bij; de pagina wordt nog steeds identiek weergegeven, omdat de actieve taal nog steeds Engels is.
7.2: Configure de taallaag
Drie kleine configuratiestukken. Ten eerste, de resources in data/app.json (de lang resource brengt cookie-detectie, INI-bestandscaching en AI-ondersteunde vertaling):
{
"resources": [
"DB/DB",
"DB/model",
"DB/JSONDB",
"DB/JSON.result",
"payload",
"phlo.async",
"DOM/form",
"lang",
"cookies",
"files/INI",
"AI/AI",
"AI/OpenAI",
"security/creds"
]
}
Ten tweede, vertel de runtime waar de vertalingsbestanden zich bevinden, in www/app.php:
phlo_app(
id: 'Poll',
host: 'localhost',
build: true,
debug: true,
app: dirname(__DIR__).'/',
langs: dirname(__DIR__).'/langs/',
);
Elke benoemde parameter van phlo_app() wordt een app-brede constante, dus langs is nu een pad dat jij (en de lang resource) overal kunt gebruiken. Maak de map aan: mkdir app/langs.
Ten derde, verklaar de talen van de app in app.phlo:
prop lang = 'en'
prop langs = ['en' => 'English', 'nl' => 'Nederlands']
Herbouw en lint; beide eindigen op [].
7.3: Een /nl route prefix
De actieve taal staat op %app->lang. Stel deze in via de URL met een tweede route in poll.phlo:
route GET poll => $this->home
route GET $lang:nl poll {
%app->lang = $lang
$this->home
}
$lang:nl is een waarde-lijst segment: het matcht alleen wanneer het eerste padsegment letterlijk nl is. Met meer talen breid je de lijst uit: $lang:nl,de,fr. De Engelse route behoudt de schone URL; de geprefixeerde route stelt de taal in en rendert dezelfde pagina.
Open http://localhost/nl/poll. De <html lang="nl"> attribuut volgt %app->lang, maar de koptekst leest nog steeds Engels: er is nog geen Nederlandse vertaling.
7.4: De vertaalcache
Vertalingen bevinden zich in langs/<lang>.ini, één regel per string, gekeyed op een hash van de brontekst. Wanneer een gemarkeerde string geen invoer heeft voor de actieve taal, toont de pagina de brontekst en plant een achtergrondvertaling via OpenAI; het volgende verzoek leest het gecachte resultaat. Voor die backfill om te werken, zet een API-sleutel in data/creds.ini:
OpenAI = sk-...
Geen sleutel? Alles werkt nog steeds, ontbrekende strings blijven gewoon in de brontaal. Je kunt het bestand ook zelf schrijven; na de eerste backfill ziet langs/nl.ini er als volgt uit:
enWhichStad3 = "Welke stack wint?"
De sleutel encodeert de brontaal plus een hash van de exacte tekst, zodat gewijzigde brontekst een nieuwe invoer krijgt. Herlaad http://localhost/nl/poll zodra de invoer bestaat:
<h1>Welke stack wint?</h1>
Zelfde view, dezelfde route-logica, tweede taal. De poll is nog maar één hoofdstuk verwijderd van voltooiing: het kan nog steeds geen resultaten naar andere kijkers pushen.