Skip to content

Tutorial 5 Localization nl

James Morris edited this page Jul 29, 2026 · 1 revision

Tutorial 5 · Lokalisatie (i18n)

🌎 Taal: Nederlandsbekijk alle 33 talen

Doel: begrijpen hoe LockedIn CLI 33 talen spreekt — en oefenen met een agent aansturen om er nog één toe te voegen. Lokalisatie is een fantastische agenttaak: ze is mechanisch genoeg om te delegeren, maar heeft echte beperkingen (een testbarrière, lay-outregels, grammaticareview) die je leren om te reviewen.

← Vorige: Tutorial 4 Prompting en review · Terug naar Start


Wat "gelokaliseerd" hier betekent

Draai de CLI in Spaans, Hindi, Japans, Vereenvoudigd Chinees of een andere meegeleverde taal en alles verandert — de splash, de helptabel, de uitvoer van elk commando, de chatsessie, zelfs de juridische kleine lettertjes. Niet alleen de grappen: het hele zichtbare oppervlak.

lockedin --lang nl post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh aura

De taal wordt automatisch gedetecteerd bij het opstarten, in deze volgorde:

  1. de --lang-optie (--lang nl, --lang=fr, -l ja)
  2. de omgevingsvariabele LOCKEDIN_LANG
  3. je locale (LC_ALL / LC_MESSAGES / LANG, daarna de OS-/runtime-locale)
  4. Engels, als fallback

normalizeLang() gebruikt normaal de primaire subtag van de locale. Dat betekent dat de-DE de selecteert, maar tlh niet per ongeluk tl wordt; de echte aliassen fil en tgl mappen bewust naar Tagalog (tl), Noors nb en nn mappen naar no, het historische Indonesische in mapt naar id, en het historische Hebreeuwse iw mapt naar he. Twee regionale codes blijven letterlijk behouden in plaats van te worden teruggebracht naar hun primaire subtag: pt-BR/pt_BR selecteren de canonieke regionale code, terwijl het algemene pt de achterwaarts compatibele bundle voor Braziliaans Portugees blijft (beide zijn Braziliaans Portugees en delen dezelfde pools/UI), en en-SG/en_SG houden Singlish vast (algemeen en blijft Engels). Traditioneel Chinees uit Hongkong is hetzelfde soort uitzondering: zh-HK, zh_HK.UTF-8 en zh-Hant-HK selecteren zh-HK, terwijl algemeen zh en tags van het vasteland Vereenvoudigd Chinees (zh) selecteren.

Onderweg wisselen — het /language-paneel. De CLI kon altijd al in een andere taal starten (--lang, LOCKEDIN_LANG); nu kun je halverwege de sessie wisselen. Typ /language (aliassen /lang en /languages) om alle 33 talen per code te tonen, elk in zijn eigen schrift; /language el wisselt voor de rest van de sessie. Het punt is de nooduitgang: na een wissel tekent de CLI opnieuw in de nieuwe taal en print dan, in de taal die je net verliet, de exacte weg terug — nu /language en, volgende keer lockedin --lang en — zodat per ongeluk landen in 日本語 of ಕನ್ನಡ je nooit strandt. (Wissel twee keer en dan wordt ook de taal aangeboden die je LOCKEDIN_LANG noemt.) --lang en LOCKEDIN_LANG blijven ongewijzigd. Net als /a11y is het een oprechte utility, geen onderdeel van de satire.

Het idee: talenbundels

Alle vertaalbare tekst leeft in bundels, één per taal, elk met deze vorm:

{ meta: { lang: 'nl', name: 'Nederlands', dir: 'ltr' },
  pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
  ui:    { buzzwordDensity: 'Buzzword density: ', /* labels, koppen */ } }
  • pools zijn de contentarrays (de grappen) die je in hoofdstuk 2 ontmoette.
  • ui zijn de UI-strings: labels, koppen en kleine templates.

Engels is de referentiebundle binnen src/lockedin.js; de andere 32 bundlemodules leven in src/content/*.js: ar, bn, bo, de, el, en-SG, es, eu, fa, fi, fr, he, hi, id, is, it, ja, kn, ms, nl, no, pl, pt, pt-BR, ru, sv, tl, tr, uk, ur, zh en zh-HK (pt-BR hergebruikt de pools/UI van pt, maar wordt apart geregistreerd). Elke bundle staat in BUNDLES; SUPPORTED_LANGS wordt uit die keys gegenereerd, en renderHelp() print die gegenereerde codelijst. Geen enkele UI-bundle hardcodet de lijst.

setLang('fr');       // wijs de actieve taal naar de Franse bundle
// L = actieve pools, U = actieve ui
pick(L.HOOKS)        // een Franse hook
U.buzzwordDensity    // "Densité de jargon : "

Omdat elke renderer L en U leest (nooit een hardcoded string), verandert setLang in zijn eentje de hele ervaring. Dat is de hele truc.

Het vangnet: sleutelpariteit

Dit is de invariant die het veilig maakt om een taal toe te voegen:

Elke bundle moet exact dezelfde pools- en ui-keys hebben als Engels.

Een test dwingt dat af in alle 33 bundles. Als je een nieuwe UI-string aan Engels toevoegt en vergeet hem in het Oekraïens te vertalen, springt npm test op rood en vertelt het je welke key ontbreekt. Je kunt geen halfvertaalde taal stilletjes uitleveren.

Het moeilijke deel: terminalindeling

Talen belasten terminalindeling op verschillende manieren:

  • Japans, Vereenvoudigd Chinees en Traditioneel Chinees uit Hongkong gebruiken East Asian Wide / Fullwidth-tekens. vw() telt die als twee kolommen, en wrap() breekt lange tokens zonder spaties hard af zodat CJK-tekst binnen kaarten en kaders blijft.
  • Hindi en Kannada gebruiken niet-spatiërende/omsluitende combining marks (Mn / Me), zoals matra's en virama's. vw() telt die als nul kolommen zodat ze de gemeten breedte niet opblazen.
  • box() wrapt elke bodyregel vóór het opvullen, zodat een lange vertaalde banner niet meer door de rand heen kan slaan.
  • Elke bundle zet sentenceEnd en listSep (bijvoorbeeld . / , , / ) zodat door generators samengestelde zinnen natuurlijk lezen.

Wanneer je een taal toevoegt, moeten kaartkopstrings (cardSubtitle, cardMeta, cardFooter) nog steeds ≤ 60 zichtbare kolommen blijven. Arabisch, Perzisch, Hebreeuws en Urdu zetten meta.dir: 'rtl'. Uitvoer bevat standaard geen bidi-controls, omdat sommige terminals die als gelabelde vakjes renderen. LOCKEDIN_BIDI=on zet expliciet gebalanceerde isolates aan na het wrappen voor terminals waarvan bekend is dat ze die ondersteunen, met behoud van ANSI, ASCII-commando's en logische kopieer-/plakvolgorde. Toegankelijke uitvoer verwijdert die controls altijd. Zonder die opt-in kan gemengde RTL/LTR-volgorde minder verfijnd zijn; sondeer of leid ondersteuning nooit af.

Het verraderlijke deel: grammatica rond ruwe gebruikersinvoer

Sommige UI-templates plakken ruwe gebruikersclausules in met placeholders zoals {cap}. Vertaal die niet vakje voor vakje. De zin moet grammaticaal blijven wanneer de placeholder een uitdrukking is die de gebruiker typte, niet een net zelfstandig naamwoord.

Een echte waarschuwingsbug: Japanse templates die direct na {cap} zetten, kunnen vreemd klinken wanneer {cap} een volledige bijzin is. De oplossing is niet "harder vertalen"; het is de template herstructureren (bijvoorbeeld een nominalisator toevoegen of de placeholder verplaatsen) zodat willekeurige gebruikersinvoer nog steeds past.

✅ Probeer het met je agent — voeg een taal toe

Deze oefening werkt nog steeds precies hetzelfde. Kies een taal die je kunt sanity-checken (of vraag de agent dat te doen), en stuur hem van begin tot eind aan. Schrijf eerst de specificatie:

Voeg Deens (da) toe. Maak src/content/da.js als een { meta, pools, ui }- bundle met dezelfde keys als Engels, en vertaal elke entry (contentpools van ~25 elk, alle UI-strings). Registreer da in BUNDLES in src/lockedin.js. --lang da en een da-*-locale moeten die kiezen. Houd kaartkopstrings binnen de breedtelimiet. npm test moet groen blijven, en voeg Deense invariant- en detectietests toe die de bestaande gelokaliseerde tests spiegelen.

Draai daarna de lus uit hoofdstuk 3–4:

  1. Eerst plannen. "Voordat je code schrijft, vertel me welke bestanden je gaat aanpassen en hoe je key parity met Engels bewaart."
  2. Eerst tests. "Voeg falende tests toe: da-detectie, key parity voor da, en een Deense reflect/connect-invariant. Maak de bundle nog niet."
  3. Implementeer. "Maak nu src/content/da.js door een bestaande bundle key voor key te vertalen, registreer hem en laat de tests slagen. Alleen pick/shuffle voor willekeur."
  4. Barrière + review. npm test, daarna lockedin --lang da post — en lees de diff: is elke key vertaald? Lopen de kaartranden nog gelijk? Kunnen templates met {cap} ruwe gebruikersclausules nog aan?

Kleinere opwarmoefeningen als een hele taal te veel is:

  • "Voeg nog één TAGLINE toe aan alle 33 talenbundels, en houd de aantallen gelijk."
  • "Controleer of de Kannada-cardFooter ≤ 60 zichtbare kolommen is, en leg uit hoe combining marks zijn gemeten."
  • "Laat me de test zien die zou falen als ik een ui-key uit ja.js verwijder."

Waar je hierna heen kunt

  • Bekijk src/content/es.js — het is nog steeds een vriendelijke template voor een nieuwe bundle.
  • Lees docs/HANDOFF.md → "Adding a language" opnieuw.
  • Geniet van de meertalige grappen in de Commandoreferentie.

Dat is de volledige tutorial. Je kunt nu een AI-agent aansturen om features te bouwen en te lokaliseren achter een testbarrière — in 33 talen en klaar voor meer. Mee eens? 👇

📘 LockedIn CLI wiki

Tutorial

Reference


Satire · Sátira · 風刺. Not affiliated with LinkedIn. GPL-3.0-or-later.

Clone this wiki locally