Work In Progress

This book is currently work in progress. Some sections are not yet written. Thank you for your understanding!

Language files

The Joomla language files have not really changed much since Joomla 1.0. Joomla is using the INI format with a few twists:

  • The keys must always be in UPPERCASE. You cannot have keys in lowercase or MixedCase.

  • The values to the right of the equals sign must be enclosed in double quotes (").

  • If you want to use double quotes inside your values you need to escape them as \".

  • Some language strings are used in JavaScript code using a legacy method. They do not support escaped double quotes. Use single quotes (') instead, even for HTML attributes (yes, HTML allows you to do things like <a href='https://www.example.com'>example</a> even though attribute values should use double quotes for compatibility with XHTML). If you want to put quotes around human-readable text you can also use calligraphic quotes: “ ” ‘ ’ and so on.

  • You can comment a line by putting a semicolon (;) as its first character. Do not put semicolons at the end of strings, they might be parsed as part of the value.

No more language tags in filenames

There is a pretty big change for language file naming in Joomla 4 and beyond: you must not use the language prefix.

In Joomla 1.5 to 3.10 inclusive language files were named like en-GB.plg_system_example.ini (British English), de-DE.plg_system_example.ini (German, Germany) and de-AT.plg_system_example.ini (German, Austria).

However, that naming was highly redundant as starting with Joomla 1.6 in 2010 the language files had to be placed in a folder whose name was the language tag itself! Inside a language folder you'd have the relative filepaths en-GB/en-GB.plg_system_example.ini, de-DE/de-DE.plg_system_example.ini and de-AT/de-AT.plg_system_example.ini. Having the same language tag appear twice in a pathname didn't make sense. Therefore in Joomla 4 and beyond we no longer use the language tag prefix!

The files are now simply named similar to plg_system_example.ini. The language of the file is inferred from the folder name it's in. For example, the filepath en-GB/plg_system_example.ini obviously refers to British English.

Plugin language files

A plugin has multiple different language files. The base name of all files is the name of the Joomla component extension, e.g. plg_system_example(the two latter parts separated by underscores is the plugin type a.k.a. folder and the plugin name, in all lowercase):

  • plg_system_example.sys.ini — System language file. Required. It only needs the two language keys for the plugin name and its XML manifest file's description. Used during installation.

  • plg_system_example.ini — Language file. Required. Has the language keys for all of the plugin's options. Also needs the two language keys for the plugin name and its XML manifest file's description. It can also contain any language strings you are using during the execution of your plugin.

Plugin language files are placed in the administrator application's language subdirectory — even for plugins which ONLY run in the frontend of the site! For example, the language files for British English are placed in administrator/language/en-GB. Moreover, Joomla will fall back to the language subdirectory under your plugin. For example, the language files for British English are also sought for in plugins/system/example/language/en-GB. If files exist in both locations then only the one in the application's directory will be loaded.

Language file autoloading

Unlike previous versions of Joomla, you do NOT have to load your language files manually. Joomla loads your plugin's language files automatically.

All you need to do is set the protected property autoloadLanguage to true in your constructor:

public function __construct(&$subject, $config = array())
{
    $this->autoloadLanguage = true;

    parent::__construct($subject, $config);
}
[Important]Important

The parent constructor method must be called AFTER setting the property. Otherwise your language files will not be loaded.

If you prefer to load the language files of your plugin only when they are absolutely needed you just need to call:

$this->loadLanguage();

Since Joomla 3.3 (based on my recollection, +/- 1 minor version…) Joomla will load language files in this order:

  • (Only if Debug Language is disabled). The language file for the site's default language (en-GB, unless a third party extension has changed it).

  • The currently active language's normative INI file (e.g. plg_system_example.ini) or legacy INI file (e.g. en-GB.plg_system_example.ini).

Joomla will first look in the administrator application's language folder i.e. administrator/language . This applied even if you are in the frontend of the site, the API application or the CLI application.

If neither the current language's, nor the default language's files have been found Joomla will fall back to your plugin's language directory. That is to say, your plugin's language directory is a last resort and not guaranteed to be used!

You may wonder: why does Joomla load both the default language (British English in most cases) and my current language (e.g. Canadian French) files? The reason is simple. All plugins are required to provide a complete language file for the default language which for Joomla is British English (en-GB). Translation to other languages are optional and often incomplete. Sometime around 2012 we decided that it makes far more sense to show an English, human-readable string to non-English speakers they can look up in the dictionary or their favorite translation tool than an incomprehensible language key like PLG_SYSTEM_EXAMPLE_CONFIG_EARLY_PREP_ARRAY_LABEL. Of course this makes it harder for translators. That's why the Debug Language feature was simultaneously introduced. When enabled, the default language is not enabled and untranslated strings are marked clearly in the output.

Defining language files in your XML manifest

Your XML manifest needs one set of <languages> tags under the <extension> root:

<extension>
<!-- … -->
<languages folder="language">
    <language tag="en-GB">en-GB/plg_system_example.ini</language>
    <language tag="en-GB">en-GB/plg_system_example.sys.ini</language>
    <language tag="de-DE">de-DE/plg_system_example.ini</language>
    <language tag="de-DE">de-DE/plg_system_example.sys.ini</language>
</languages>
<!-- … -->
</extension>

This copies the files from the language/ folder in your package to Joomla's admin language folder, e.g. the language/en-GB/plg_system_example.ini file in your package to administrator/language/en-GB/plg_system_example.ini file on your site.

Language overrides

Language overrides are loaded before any of your language files, at the initialisation of the CMSApplication object, namely when the Language object is constructed. They are stored in the file language/overrides/LANGUAGE_TAG.override.ini under the application's root (site root for the frontend, administrator for the backend, api for the API application) where LANGUAGE_TAG is the current language's tag, e.g. en-GB for British English.

[Warning]Warning

Overrides for the frontend and the backend of the site are different for plugins! Even though the plugin's language files are always stored in the backend (even if it runs in the frontend of the site), the overrides Joomla loads if the plugin is executing in the frontend of the site are those set for the site's frontend or marked as for both front- and backend.

If you think about it, it makes sense. The frontend and backend of the site target different kinds of users. The public frontend may need a different worded message to address its target audience more effectively.

The way it works is that your language file is loaded and then the overridden strings are replaced into the language file if and only if they are already defined in the language file.

[Caution]Caution

This means that the language overrides cannot be used for language keys not defined in your language files, unlike Joomla 3.

Since this was a widely popular “trick” to allow your users to customise the display of your components you now have to take that explicitly into account. For example, given an item with an alias foobar you might be looking for the language string PLG_SYSTEM_EXAMPLE_ITEM_OVERRIDE_FOOBAR_TITLE to override the title field of your item for display in different languages. This worked in Joomla 3 but will NOT work in Joomla 4 or later.

As noted in the language section for components, you can use custom language files to work around this problem.