Terug naar hoofdinhoud
Taalbestanden in Joomla
Op deze pagina
# Topics

Taalbestanden in Joomla

06 juni 2026

Het woord "taal" heeft binnen Joomla twee verschillende betekenissen, en die worden vaak door elkaar gehaald. Dit artikel gaat over de eerste betekenis: de taalbestanden die alle teksten van de interface bevatten. Het gaat niet over het publiceren van dezelfde website in meerdere talen.

Dat is belangrijker dan het misschien klinkt. Zelfs een website die volledig Engelstalig is, draait volledig op taalbestanden. Ze zijn niet optioneel. Zonder taalbestanden kan Joomla helemaal geen tekst op het scherm tonen.

De belangrijkste gedachte om mee te nemen is deze: Joomla hardcodeert nooit tekst die gebruikers zien. De code verwijst naar een sleutel, en een apart bestand bepaalt welke tekst daarbij hoort in een bepaalde taal. Vervang het bestand en de hele interface verandert van taal zonder dat er één regel code hoeft te worden aangepast. Zodra je begrijpt hoe het KEY="waarde"-principe werkt en in welke volgorde taalbestanden worden geladen, kun je elke tekst op een Joomla-site vertalen, overriden of uitbreiden.

Hoe taalbestanden elk woord bevatten dat Joomla aan gebruikers toont.

Dit artikel begint bij de basis voor website-eigenaren en redacteuren, gaat daarna verder met de praktische hulpmiddelen voor beheerders en eindigt met de technische details voor ontwikkelaars.

1. De basis

1.1 Twee betekenissen van "taal"

Laten we eerst de twee begrippen uit elkaar houden die binnen Joomla hetzelfde woord gebruiken:

OnderwerpTaalbestanden (dit artikel)Meertalige content (niet dit artikel)
Wat het is De vertaalbestanden van de interface Dezelfde website publiceren in meerdere talen
Omvang Knoppen, labels, meldingen en foutmeldingen Artikelen, menu's en modules per taal
Mogelijk gemaakt door Text::_() en .ini-bestanden com_languages, de plugin Language Filter en Associations
Wie heeft het nodig? Iedere ontwikkelaar en templatebouwer Websites met een meertalig publiek

In dit artikel behandelen we alleen de eerste kolom.

1.2 Taal is een extensietype

Een taal is één van Joomla's extensietypen. Een taal wordt geïnstalleerd, ingeschakeld, bijgewerkt en verwijderd net zoals elke andere extensie. Het enige verschil is dat een taalpakket uit .ini-bestanden bestaat in plaats van PHP-logica:

TypeRolPrefix
Component Hoofdinhoud of applicatie van de pagina com_
Module Kleine blokken rondom de inhoud mod_
Plugin Eventgestuurd gedrag plg_
Template Uiterlijk, stijl en pagina-indeling tpl_
Taal Vertalingen van de interface pkg_ / taalcode

1.3 De taalcode

Elke taal heeft een unieke taalcode in de vorm xx-XX: een kleine ISO-639-taalcode, gevolgd door een koppelteken en een hoofdletterige ISO-3166-regiocode.

en-GB   Engels (Verenigd Koninkrijk)   ← de brontaal van Joomla
en-US   Engels (Verenigde Staten)
nl-NL   Nederlands (Nederland)
nl-BE   Nederlands (België)
de-DE   Duits (Duitsland)
ar-AA   Arabisch                       ← van rechts naar links

De code en-GB heeft een bijzondere rol. Joomla is oorspronkelijk geschreven in deze taal en gebruikt deze als universele fallback. Als een vertaling ontbreekt in nl-NL, toont Joomla automatisch de tekst uit en-GB.

1.4 Waar de bestanden staan

Net als bij templates bestaan er twee aparte mappenstructuren, één voor elke client (front-end en back-end):

public_html/
├── language/                     ← SITE (front-end) talen
│   ├── en-GB/
│   ├── nl-NL/
│   └── overrides/                ← jouw eigen taaloverrides
└── administrator/
    └── language/                 ← ADMINISTRATOR (back-end) talen
        ├── en-GB/
        ├── nl-NL/
        └── overrides/

De front-end en back-end worden onafhankelijk van elkaar vertaald. Een bezoeker kan de website in het Nederlands zien terwijl jij de backend in het Engels gebruikt, omdat beide omgevingen verschillende taalmappen laden.

1.5 Binnenin een taalmap

Een taalmap bevat veel bestanden. Er is één .ini-bestand per extensie, aangevuld met enkele speciale bestanden:

language/en-GB/
├── joomla.ini             ← gedeelde en algemene teksten (het "woordenboek" van Joomla)
├── lib_joomla.ini         ← teksten van de frameworkbibliotheek
├── com_content.ini        ← één bestand per component ...
├── com_content.sys.ini    ← ... plus het systeemtaalbestand (zie deel 3)
├── mod_articles_latest.ini
├── plg_system_...ini
├── langmetadata.xml       ← manifest (taalcode, locale, rtl, kalender)
├── localise.php           ← taalregels (meervouden, transliteratie)
└── index.html

Eén .ini-bestand per extensie houdt alles overzichtelijk en modulair. Joomla laadt alleen de bestanden die voor de huidige pagina nodig zijn.

Naar boven

2. Het .ini-bestandsformaat

2.1 Het contract: KEY="waarde"

Een taalbestand is een opzoektabel. Elke regel koppelt een constante aan een leesbare tekst:

; Opmerkingen beginnen met een puntkomma
; Let op: alle .ini-bestanden MOETEN opgeslagen worden als UTF-8 (zonder BOM)

COM_CONTENT="Artikelen"
COM_CONTENT_SAVE="Artikel opslaan"
JGLOBAL_TITLE="Titel"

De regels zijn strikt en weinig vergevingsgezind:

RegelDetails
Codering UTF-8, zonder byte-order mark (BOM)
Aanhalingstekens De waarde staat altijd tussen dubbele aanhalingstekens: KEY="waarde"
Sleutels UPPER_SNAKE_CASE, zonder spaties en volgens de conventie voorzien van een extensieprefix
Eén per regel KEY="waarde", geen waarden over meerdere regels
Opmerkingen Regels die beginnen met ;

2.2 De valkuilen die een volledig bestand breken

Dit is belangrijk: één enkele foutieve regel kan ervoor zorgen dat het hele bestand niet meer wordt geladen. Wanneer dat gebeurt, toont Joomla niet de vertaalde tekst maar simpelweg de ruwe sleutel op het scherm.

  • Gereserveerde woorden. De woorden YES, NO, TRUE, FALSE, NULL, ON, OFF en NONE zijn gereserveerd in de INI-specificatie. Daarom staan waarden altijd tussen aanhalingstekens en gebruikt Joomla bijvoorbeeld JYES="Ja" in plaats van een kale waarde.
  • Een niet-geëscapeerd dubbel aanhalingsteken binnen een waarde. Wil je letterlijk een " tonen, dan moet je deze escapen:
; moderne Joomla - escapen met een backslash
COM_EXAMPLE_HELLO="Zeg \"Hallo\" tegen de wereld"

; oudere placeholder die nog steeds door oudere parsers wordt ondersteund
COM_EXAMPLE_HELLO_OLD="Zeg _QQ_Hallo_QQ_ tegen de wereld"
  • Geen sleutel links van het =-teken, een los =-teken of een niet-gequote waarde veroorzaakt een parsefout.

Praktische tip: schakel Global Configuration → System → Debug Language in terwijl je taalbestanden bewerkt. Joomla meldt dan de fout én het exacte regelnummer van een defect .ini-bestand.

2.3 Waarden mogen HTML en placeholders bevatten

De waarde is gewoon tekst. Deze mag HTML, HTML-entiteiten en printf-achtige placeholders bevatten zoals %s en %d, die later door de code worden ingevuld (zie deel 7):

COM_USERS_REGISTER_SUCCESS="Bedankt, <strong>%s</strong>, voor je registratie."
JLIB_HTML_BATCH_NO_CATEGORY="- Oorspronkelijke categorie behouden -"
Naar boven

3. .ini versus .sys.ini

Elke extensie bevat twee taalbestanden en niet slechts één. Dit detail verrast bijna iedereen de eerste keer.

BestandBevatWordt geladen
com_content.ini Alle runtime-teksten: labels, knoppen, meldingen en foutmeldingen binnen de component Wanneer de component daadwerkelijk wordt uitgevoerd
com_content.sys.ini Een kleine set met de naam van de extensie, beschrijvingen, menu-items en installatieteksten Vroeg en vaak, bijvoorbeeld door de extensiebeheerder, menubouwer en moduleoverzichten
com_content.sys.ini  (klein, altijd snel te laden)
└── COM_CONTENT="Artikelen"
└── COM_CONTENT_XML_DESCRIPTION="De artikelencomponent ..."

com_content.ini      (groot, alleen geladen wanneer de component rendert)
└── COM_CONTENT_SAVE, COM_CONTENT_N_ITEMS_ARCHIVED, ... (honderden sleutels)

Vuistregel: als een tekst zichtbaar moet zijn voordat de extensie wordt uitgevoerd, bijvoorbeeld in het installatiescherm, de extensielijst of de keuze van een menutype, dan hoort deze thuis in .sys.ini. Alle andere teksten horen in het gewone .ini-bestand.

Naar boven

4. Bestandsnamen en locaties

4.1 De moderne conventie (core)

Taalbestanden van de Joomla-core staan centraal opgeslagen en worden benoemd zonder taalprefix. Omdat de mapnaam de taal al aangeeft, hoeft die niet opnieuw in de bestandsnaam te worden opgenomen:

administrator/language/en-GB/com_content.ini
administrator/language/en-GB/com_content.sys.ini
language/en-GB/com_content.ini

4.2 De oudere vorm met taalprefix (nog steeds geldig)

Oudere extensies en veel extensies van derden gebruiken nog steeds bestandsnamen met een taalprefix. De populaire JCE-editor doet dit bijvoorbeeld nog steeds:

language/en-GB/en-GB.com_jce.ini
language/en-GB/en-GB.pkg_jce.sys.ini

Beide vormen werken prima. Hieronder staan ze naast elkaar:

StijlVoorbeeldGebruikt door
Zonder prefix (modern) com_content.ini Joomla 6 core
Met prefix (ouder) en-GB.com_jce.ini oudere extensies en extensies van derden

4.3 Taalbestanden meeleveren binnen de extensie

Een moderne extensie van derden hoeft haar taalbestanden niet meer in de centrale taalstructuur te installeren. De extensie kan een eigen map language/ bevatten, die Joomla direct vanaf die locatie laadt:

com_example/
├── com_example.xml
├── src/ ...
└── language/
    └── en-GB/
        ├── com_example.ini
        └── com_example.sys.ini

Het voordeel van vertalingen binnen de extensie bewaren is dat updates automatisch ook de juiste taalbestanden meeleveren. Na het verwijderen van de extensie blijven er bovendien geen verweesde bestanden achter in /language/.

Naar boven

5. Anatomie van een taalpakket

Een volledig taalpakket, bijvoorbeeld nl-NL, is zelf een installeerbare extensie. Naast de gebruikelijke .ini-bestanden bevat het drie speciale onderdelen.

5.1 langmetadata.xml, het manifest

Dit bestand (vóór Joomla 4 bekend als xx-XX.xml) beschrijft de taal voor het volledige systeem:

<metafile client="site">
    <name>Engels (en-GB)</name>
    <version>6.1.0</version>
    <metadata>
        <tag>en-GB</tag>
        <rtl>0</rtl>                       <!-- 1 = van rechts naar links -->
        <locale>en_GB.utf8, en_GB, english</locale>
        <firstDay>0</firstDay>             <!-- 0 = zondag -->
        <weekEnd>0,6</weekEnd>
        <calendar>gregorian</calendar>
    </metadata>
</metafile>

Dit bestand bepaalt de locale voor PHP-datum- en nummerfuncties, de rechts-naar-links-instelling die templates gebruiken en de eerste dag van de week in kalenderweergaven.

5.2 localise.php, taalspecifieke regels

Sommige logica past niet in een eenvoudig .ini-bestand. Regels voor meervouden verschillen per taal, daarom kan elk taalpakket een kleine PHP-klasse bevatten:

abstract class En_GBLocalise
{
    // Welke meervoudsvorm hoort bij een bepaald aantal?
    public static function getPluralSuffixes($count)
    {
        return $count == 1 ? ['1'] : ['MORE'];
    }

    // (sommige talen definiëren ook transliterate(), zoekwoordregels, ...)
}

Engels kent twee meervoudsvormen, Pools drie en Arabisch zelfs zes. De methode getPluralSuffixes() bepaalt hoe Text::plural() (zie deel 7) de juiste vertaalsleutel kiest.

5.3 De map overrides/

Elke client heeft een map overrides/ met daarin één bestand, xx-XX.override.ini, dat altijd voorrang krijgt op alle andere taalbestanden. Dit is de gebruiksvriendelijke overridefunctie die in deel 10 wordt behandeld:

language/overrides/en-GB.override.ini
administrator/language/overrides/en-GB.override.ini

Wanneer dezelfde sleutel zowel in een normaal taalbestand als in een overridebestand voorkomt, gebruikt Joomla altijd de waarde uit het overridebestand.

Naar boven

6. Vertalingen gebruiken in code

6.1 Text::_(), het werkpaard

Je toont in code nooit letterlijk een tekst die zichtbaar is voor gebruikers. In plaats daarvan gebruik je een sleutel, waarna de klasse Text de juiste vertaling opzoekt:

use Joomla\CMS\Language\Text;

echo Text::_('COM_CONTENT_SAVE');     // "Artikel opslaan" (of "Save Article" in en-GB)

De opzoekactie verloopt als volgt:

Text::_('COM_CONTENT_SAVE')
        |
        v
zoek 'COM_CONTENT_SAVE' op in de geladen taalbestanden
        |
   +----+-------------+
 gevonden?          niet gevonden?
   |                   |
 retourneer waarde  retourneer de SLEUTEL zelf  (zichtbare aanwijzing)

Wanneer je letterlijk COM_CONTENT_SAVE op het scherm ziet verschijnen, betekent dat dat Joomla de sleutel niet heeft kunnen vinden. De oorzaak is meestal een verkeerd bestand, een bestand dat niet is geladen of een typefout in de sleutel.

6.2 De Text-familie

De klasse Text bevat verschillende statische methoden voor uiteenlopende vertaaldoeleinden:

AanroepGebruik
Text::_('KEY') Gewone vertaling
Text::sprintf('KEY', $a, $b) Waarden invoegen in %s- of %d-placeholders
Text::plural('KEY', $n) Meervoudsafhankelijk (1 item / meerdere items)
Text::script('KEY') Een vertaling beschikbaar maken voor JavaScript
Text::alt('KEY', 'COMPONENT') Een contextspecifieke alternatieve sleutel gebruiken

Al deze methoden bevinden zich in Joomla\CMS\Language\Text. De oudere notatie JText::_() is hetzelfde mechanisme onder de oude naam van vóór namespaces.

6.3 Vertalingen in XML, zonder PHP

Een groot deel van alle vertaalbare teksten komt nooit in PHP-code terecht. Formuliervelden, configuratieopties, menutypes en installatiemanifesten zijn XML-bestanden. Joomla vertaalt automatisch de attributen label en description. Je hoeft daar alleen de sleutel te plaatsen:

<!-- een configuratie- of formulierveld: de attributen ZIJN vertaalsleutels -->
<field
    name="title"
    type="text"
    label="COM_EXAMPLE_FIELD_TITLE_LABEL"
    description="COM_EXAMPLE_FIELD_TITLE_DESC"
/>
; ...wordt opgehaald uit je .ini-bestand, net als bij Text::_()
COM_EXAMPLE_FIELD_TITLE_LABEL="Titel"
COM_EXAMPLE_FIELD_TITLE_DESC="De koptekst die bovenaan de pagina wordt weergegeven."
Waar de sleutel voorkomtWordt vertaald door
label= / description= in config.xml en formulier-.xml-bestanden De formulier- en veldrenderer
<menu>, <submenu> in het componentmanifest De menubouwer (vereist een .sys.ini-bestand)
<name>, <description> in een manifestbestand De extensiebeheerder (vereist een .sys.ini-bestand)

Dit verklaart precies waarom het .sys.ini-bestand uit deel 3 noodzakelijk is. Het installatiescherm, de extensielijst en de menutypekiezer moeten deze XML-teksten kunnen vertalen voordat het gewone .ini-bestand wordt geladen.

Naar boven

7. Placeholders en meervouden

7.1 Text::sprintf(), waarden invoegen

Het .ini-bestand bevat de placeholders en de code levert de daadwerkelijke waarden aan:

COM_CONTENT_N_ITEMS_ARCHIVED="%d artikelen gearchiveerd."
echo Text::sprintf('COM_CONTENT_N_ITEMS_ARCHIVED', $count);
// $count = 5  ->  "5 artikelen gearchiveerd."

Doordat het getal niet hardcoded in de tekst staat, kunnen vertalers de woordvolgorde aanpassen aan hun eigen taal. Dat is essentieel voor talen waarin het werkwoord of het getal op een andere plaats in de zin staat.

7.2 Text::plural(), grammaticaal correcte aantallen

"1 artikel" versus "5 artikelen" is niet zomaar een eenvoudige if-constructie. Joomla bouwt de sleutel op uit een basissleutel plus een meervoudsachtervoegsel, terwijl localise.php bepaalt welk achtervoegsel gebruikt moet worden:

COM_CONTENT_N_ITEMS_ARCHIVED="%d artikelen gearchiveerd."   ; standaard / MORE-vorm
COM_CONTENT_N_ITEMS_ARCHIVED_1="Artikel gearchiveerd."      ; enkelvoud
echo Text::plural('COM_CONTENT_N_ITEMS_ARCHIVED', $n);

// $n = 1  -> sleutel ..._1     -> "Artikel gearchiveerd."
// $n = 7  -> sleutel ..._MORE  -> "7 artikelen gearchiveerd."

De verwerking verloopt als volgt:

Text::plural('..._ARCHIVED', $n)
        |
        v
getPluralSuffixes($n)  ->  ['1']  of  ['MORE']
        |
        v
probeer ..._ARCHIVED_1  /  ..._ARCHIVED_MORE
(val terug op ..._ARCHIVED indien nodig)

Dit is één van de belangrijkste redenen waarom een taal meer is dan alleen een woordenlijst. Grammatica is logica, en die logica zit in localise.php.

Naar boven

8. Vertalingen in JavaScript

De browser kan geen .ini-bestanden lezen. De methode Text::script() overbrugt dat probleem door een vertaalsleutel toe te voegen aan een JavaScript-woordenboek dat Joomla tijdens het renderen op de pagina plaatst:

Text::script('COM_CONTENT_CONFIRM_DELETE');   // PHP tijdens het renderen
// later, in je JavaScript:
alert(Joomla.Text._('COM_CONTENT_CONFIRM_DELETE'));

Joomla verzamelt alle sleutels die via Text::script() zijn geregistreerd en genereert hiervan een Joomla.Text-object. Hierdoor blijft client-side code net zo vertaalbaar als PHP-code.

Naar boven

9. Laden en laadvolgorde

9.1 Het meeste laden gebeurt automatisch

Wanneer de dispatcher bijvoorbeeld com_content uitvoert, laadt Joomla automatisch com_content.ini voor de actieve taal en client. Handmatig laden is zelden nodig, maar het kan wel:

$lang = $this->getLanguage();              // of Factory::getApplication()->getLanguage()
$lang->load('com_content', JPATH_ADMINISTRATOR);   // laad expliciet de taalstrings van een andere extensie

9.2 De cascade, laatst geladen wint

Vertalingen worden samengevoegd tot één grote opzoektabel terwijl bestanden worden geladen. Een latere definitie overschrijft altijd een eerdere:

1. joomla.ini / lib_joomla.ini   (algemeen woordenboek)
2. com_xxx.ini                   (de component)
3. template- en modulestrings
4. en-GB.override.ini            (OVERRIDES - altijd als laatste, winnen altijd)
        |
        v
één samengevoegde KEY -> waarde-opzoektabel voor dit verzoek

Omdat overrides als laatste worden geladen, hebben ze altijd voorrang op teksten uit de core of extensies. Dat maakt de overridefunctie uit deel 10 zowel veilig als krachtig.

9.3 Fallback naar en-GB

Wanneer een vertaling ontbreekt, geeft Joomla niet direct op:

Zoek 'COM_X_FOO' in nl-NL
   |
bestaat in nl-NL.ini?  -- ja -> gebruik deze waarde
   | nee
bestaat in en-GB.ini?  -- ja -> gebruik Engels (veilige fallback)
   | nee
toon de SLEUTEL letterlijk  (teken dat deze nergens bestaat)

Dankzij deze fallback blijft een website bruikbaar, zelfs wanneer een vertaling nog niet volledig is afgerond.

Naar boven

10. Taaloverrides (zonder bestanden, zonder FTP)

10.1 De ingebouwde tool

Via System → Manage → Language Overrides kun je elke tekst aanpassen, zowel uit de Joomla-core als uit extensies, rechtstreeks vanuit de beheeromgeving en per taal en per client:

System → Language Overrides
   ├── kies taal + Site/Administrator
   ├── zoek de bestaande sleutel (bijvoorbeeld "COM_CONTENT_ARTICLES")
   └── sla je vervangende tekst op
        |
        v  schrijft naar
language/overrides/en-GB.override.ini

Omdat overrides als laatste worden geladen, krijgt jouw tekst altijd voorrang. En omdat je geen corebestand wijzigt, blijven je aanpassingen behouden na updates.

Een klassiek voorbeeld is het hernoemen van "Artikelen" naar "Nieuws", of het vriendelijker formuleren van een foutmelding. Sitebreed, binnen enkele seconden en volledig updatebestendig.

10.2 Debug Language, ontdek de sleutel achter elke tekst

Schakel Global Configuration → System → Debug Language in. Joomla markeert dan elke vertaalde tekst zodat je kunt zien welke sleutel wordt gebruikt:

  • **KEY** rond een tekst betekent dat deze wel vertaald is en toont de gebruikte sleutel.
  • ??KEY?? betekent dat de sleutel niet gevonden werd (ontbrekende of niet-geladen vertaling).

Zo ontdek je eenvoudig de exacte sleutel die je nodig hebt voor een override. Geen giswerk en geen zoektocht door bestanden.

Naar boven

11. Het algemene woordenboek

11.1 joomla.ini, gedeelde teksten voor iedereen

Algemene, herbruikbare teksten staan centraal in joomla.ini, zodat elke extensie ze kan gebruiken en een override direct overal effect heeft:

ERROR="Fout"
WARNING="Waarschuwing"
JYES="Ja"
JNO="Nee"
JALL="Alles"
JGLOBAL_TITLE="Titel"
JACTION_CREATE="Aanmaken"
JACTION_DELETE="Verwijderen"

Het voorvoegsel J geeft aan dat het om een algemene Joomla-tekst gaat. Gebruik daarom liever JGLOBAL_TITLE dan een nieuwe sleutel zoals COM_MYTHING_TITLE te verzinnen. Die vertaling bestaat immers al in elk taalpakket.

11.2 Ook datum- en getalnotaties zijn vertaalbaar

Het bestand joomla.ini bepaalt niet alleen woorden, maar ook hoe datums worden weergegeven, via PHP-date()-patronen:

DATE_FORMAT_LC  = "l, d F Y"      ; maandag, 01 juni 2026
DATE_FORMAT_LC2 = "l, d F Y H:i"  ; ... 14:30
DATE_FORMAT_LC4 = "Y-m-d"         ; 2026-06-01

Vertalers kunnen zowel de namen van maanden en dagen als de volgorde van datumonderdelen aanpassen. Daardoor worden datums vanzelf op een natuurlijke manier weergegeven in elke taal, zonder codewijzigingen.

Naar boven

12. Locale, RTL en kalenders

De metadata uit langmetadata.xml (deel 5.1) bepaalt veel meer dan alleen vertalingen:

InstellingEffect
<locale> Stelt de PHP-locale in voor correcte notatie van getallen, valuta en datums
<rtl> 1 schakelt de volledige interface om naar rechts-naar-links; templates laden dan *-rtl.css
<firstDay> Bepaalt de eerste dag van de week in alle datumkiezers (0 = zondag, 1 = maandag)
<weekEnd> Bepaalt welke dagen als weekend worden weergegeven
<calendar> gregorian of andere kalendersystemen voor datumvelden
Talen van rechts naar links (rtl=1): ar-AA (Arabisch), he-IL (Hebreeuws), fa-IR (Perzisch)
   -> <html dir="rtl">, gespiegelde layout, template-rtl.min.css

Vertalen gaat over woorden. Lokalisatie gaat over datums, meervouden, leesrichting en kalenders. Een volledig taalpakket doet beide, en alles wordt via configuratiebestanden geregeld in plaats van via code.

Naar boven

13. Taal en de database

13.1 De grote verrassing, vertalingen staan niet in de database

Dit verrast veel beheerders. Joomla bewaart vertalingen volledig in bestanden. Er bestaat geen vertaaltabel. De .ini-bestanden op schijf zijn de vertaalgegevens. De database houdt alleen bij welke talen bestaan en welke taalpakketten geïnstalleerd zijn:

TEKSTEN (de woorden)        -> .ini-bestanden op schijf           (NIET in de database)
WELKE TALEN BESTAAN         -> #__languages                       (enkele records)
"taal is geïnstalleerd"     -> #__extensions                      (type='language')
OVERRIDES                   -> overrides/xx-XX.override.ini       (NIET in de database)

13.2 De drie tabellen die wel meedoen

TabelBevat
#__extensions Eén record per geïnstalleerd taalpakket: type='language', element = de taalcode (nl-NL), client_id (0 site / 1 administrator), enabled en een manifest_cache-snapshot van langmetadata.xml
#__languages Eén record per taal die de website kent: lang_code (en-GB), title, sef (en), image, published, access en ordering. Deze tabel wordt gebruikt door de taalwisselaar en beheeroverzichten
#__menu (indirect) Per taal verwijzen startpagina's en toewijzingen naar de kolom language. Dit wordt vooral relevant bij meertalige websites (buiten de scope van dit artikel)
SELECT extension_id, element, client_id, enabled
FROM   #__extensions
WHERE  type = 'language';        -- alle geïnstalleerde taalpakketten, site + administrator

SELECT lang_code, title, sef, published
FROM   #__languages;             -- alle talen die de website kent

13.3 Waarom er geen override-tabel bestaat

De tool Language Overrides uit deel 10 wijzigt teksten, maar schrijft niets naar de database. In plaats daarvan wordt er toegevoegd aan overrides/en-GB.override.ini op schijf:

System → Language Overrides   --schrijft naar-->   language/overrides/en-GB.override.ini
                                                    (een gewoon .ini-bestand, als laatste geladen -> wint altijd)

Omdat overrides gewone bestanden zijn, kun je ze eenvoudig back-uppen, vergelijken in Git en samen met de rest van de website uitrollen. Ze blijven bovendien bestaan, zelfs wanneer je een databasebackup terugzet. :contentReference[oaicite:0]{index=0}

Naar boven

14. Joomla zelf vertalen

14.1 Een taalpakket installeren

Via System → Install → Languages zie je alle taalpakketten van erkende vertaalteams. Joomla downloadt en installeert deze rechtstreeks vanaf de updateserver, zowel voor de website als voor de beheeromgeving:

System → Install → Languages
   -> kies "Nederlands (nl-NL)"  -> Installeren
   -> daarna beschikbaar als standaardtaal voor Site/Admin en per gebruiker

Na installatie stel je de standaardtaal in via System → Manage → Languages. Gebruikers kunnen daarnaast in hun profiel een eigen beheertaal kiezen.

14.2 Waar komen de vertalingen vandaan?

De vertalingen van Joomla Core worden onderhouden door vrijwillige vertaalteams via een gedeeld vertaalplatform (vroeger Transifex, tegenwoordig Crowdin). De workflow ziet er ongeveer zo uit:

en-GB .ini  (bronteksten geschreven door ontwikkelaars)
      |  uploaden
      v
   Crowdin   ← vertaalteams vullen alle talen in
      |  bouwen van taalpakketten
      v
Joomla updateserver  -> "Install Languages" op jouw website

Wanneer je zelf een nieuwe en-GB-sleutel toevoegt aan een extensie, vormt die de basis voor alle vertalers. Daarom zijn duidelijke sleutelnamen en heldere Engelstalige teksten belangrijk.

Naar boven

15. Ontwikkelen en best practices

15.1 Vertalingen toevoegen aan je eigen extensie

Voor ontwikkelaars bestaat het proces uit drie stappen:

  1. Gebruik voor elke tekst een sleutel, nooit een letterlijke tekst: echo Text::_('COM_EXAMPLE_HEADING');
  2. Definieer de sleutel in language/en-GB/com_example.ini van je extensie (en gebruik .sys.ini voor naam- en menuteksten).
  3. Lever deze bestanden mee binnen de extensie (zie deel 4.3), zodat updates automatisch ook nieuwe vertalingen bevatten.
; com_example.ini
COM_EXAMPLE_HEADING="Welkom"
COM_EXAMPLE_N_RESULTS="%d resultaten gevonden"
COM_EXAMPLE_N_RESULTS_1="Eén resultaat gevonden"

15.2 Sleutels goed benoemen

  • Gebruik een extensieprefix: COM_EXAMPLE_..., MOD_EXAMPLE_..., PLG_SYSTEM_EXAMPLE_.... Zo voorkom je naamconflicten in de gedeelde vertaaltabel.
  • Beschrijf de betekenis, niet de tekstwaarde: gebruik COM_EXAMPLE_SAVE_SUCCESS in plaats van COM_EXAMPLE_GREEN_MESSAGE.
  • Herbruik bestaande globale sleutels zoals JYES, JGLOBAL_TITLE en JACTION_* in plaats van ze opnieuw aan te maken.
  • Houd sleutels stabiel. Het hernoemen van een sleutel verbreekt alle bestaande vertalingen ervan.

15.3 Waar horen taalbestanden van een extensie thuis?

Dit is een veelgestelde vraag. Het korte antwoord: binnen de extensie zelf. Plaats ze in de eigen map language/ van de extensie. De centrale map /language/ is vooral een overblijfsel uit oudere versies en een nooduitgang voor websitebeheerders, niet de plek waar jij als ontwikkelaar je taalbestanden neerzet.

com_example/
├── com_example.xml
├── language/en-GB/com_example.ini  + .sys.ini      ← siteteksten
└── admin/language/en-GB/com_example.ini + .sys.ini ← backendteksten
AspectBinnen de extensie (aanbevolen)Centrale /language/-map (ouder)
Updates Nieuwe vertalingen worden automatisch meegeleverd Bestanden moeten apart worden gekopieerd
Verwijderen Wordt netjes opgeruimd Laat verweesde taalbestanden achter
Packaging Eén zelfstandig zipbestand Twee locaties om te beheren

De nuance is dat de centrale taalmap nog steeds voorrang krijgt wanneer daar een bestand met dezelfde naam aanwezig is. Dat is bewust zo ontworpen, zodat een websitebeheerder teksten kan overschrijven zonder jouw extensie aan te passen. In de praktijk is de tool Language Overrides hiervoor echter veel geschikter. Dus: jij als ontwikkelaar levert taalbestanden mee binnen de extensie, terwijl een websitebeheerder tekstaanpassingen doet via Language Overrides.

Naar boven

16. Veelgemaakte fouten en valkuilen

  • Teksten hardcoden met echo "Opslaan"; in plaats van Text::_('..._SAVE') maakt vertalen onmogelijk.
  • Een .ini-bestand opslaan als UTF-8 mét BOM, of in Latin-1, zorgt ervoor dat het bestand niet wordt geladen.
  • Een gereserveerd woord zonder aanhalingstekens of een niet-geëscapeerd aanhalingsteken kan ervoor zorgen dat het hele bestand stilletjes niet meer werkt.
  • Runtime-teksten in .sys.ini plaatsen vertraagt vroege laadmomenten; de extensienaam in het gewone .ini-bestand zetten betekent dat deze ontbreekt in extensie- en menulijsten.
  • Core .ini-bestanden aanpassen om teksten te wijzigen werkt slechts tijdelijk. Bij de volgende update zijn de wijzigingen weg. Gebruik Language Overrides.
  • Meervoudsvormen handmatig bouwen met $n == 1 ? ... is voor de meeste talen fout. Gebruik altijd Text::plural().
  • Vergeten om Text::script() te gebruiken zorgt ervoor dat JavaScript ruwe sleutels of uitsluitend Engelse teksten toont.
  • Een veldlabel alleen in het gewone .ini-bestand zetten kan ertoe leiden dat de sleutel letterlijk verschijnt in configuratieschermen die alleen .sys.ini laden.
  • Zoeken naar een database-tabel voor overrides heeft geen zin. Die bestaat niet, overrides zijn gewone bestanden.
Naar boven

17. In het kort

VERTALEN      echo Text::_('KEY')
WAARDE INVOEGEN  echo Text::sprintf('KEY', $count)
AANTALLEN     echo Text::plural('KEY', $n)   (+ key_1, key_MORE)
JAVASCRIPT    Text::script('KEY')  ->  Joomla.Text._('KEY')
XML-VELD      label="KEY" description="KEY"   (geen PHP nodig)
NAAM/MENU     plaats vroege teksten in .sys.ini
ALGEMEEN      hergebruik JYES, JGLOBAL_TITLE, JACTION_*
OVERRIDE      System -> Language Overrides (schrijft naar overrides/xx-XX.override.ini)
SLEUTEL VINDEN Global Configuration -> System -> Debug Language
TAAL INSTALLEREN System -> Install -> Languages
FALLBACK      ontbreekt nl-NL? -> en-GB -> ruwe KEY
Naar boven

18. Samenvatting

In Joomla zijn taalbestanden niet alleen bedoeld voor meertalige websites. Ze vormen het mechanisme waarmee Joomla überhaupt tekst op het scherm kan tonen. Ze raken vrijwel elke laag van het systeem:

  • Interface: elke knop, label, melding en foutmelding komt uit een .ini-bestand.
  • Code: Text::_(), sprintf(), plural() en script() houden teksten gescheiden van de programmalogica.
  • Configuratie: XML-attributen zoals label= en description= worden automatisch vertaald.
  • Lokalisatie: datums, meervouden, leesrichting en kalenders worden allemaal vanuit het taalpakket geregeld.
  • Onderhoud: Language Overrides maken het mogelijk om elke tekst veilig aan te passen zonder updateproblemen, met gewone bestanden die je kunt back-uppen en uitrollen.
  • Architectuur: vertalingen staan in bestanden en niet in de database, waardoor ze eenvoudig te verplaatsen, beheren en versioneren zijn.

Zodra je het KEY="waarde"-principe begrijpt, het verschil kent tussen .ini en .sys.ini, weet hoe de laadvolgorde werkt en vertrouwd bent met Language Overrides, kun je de teksten van elke Joomla-website vertalen, aanpassen of uitbreiden.

Of je nu een extensie ontwikkelt, een vertaalproject start of naar een scherm vol COM_SOMETHING-sleutels kijkt en je afvraagt waarom die zichtbaar zijn, het loont om deze laag vroeg te begrijpen. Taalbestanden vormen de stille fundering onder elk woord dat Joomla toont.

Naar boven
Taalbestanden in Joomla
Peter Martin

Joomla en Linux specialist voor snelle, veilige en schaalbare websites.