Localization
QUIQQER packages use locale.xml for translated text in PHP, JavaScript, templates, package metadata, permissions, console tools, mail texts, and backend interfaces.
Translations are grouped by package. A package usually uses its Composer package name as the locale group, for example quiqqer/bricks.
Declare Translations
Create locale.xml in the package root.
<?xml version="1.0" encoding="UTF-8"?>
<locales>
<groups name="vendor/package" datatype="php,js">
<locale name="package.title">
<de><![CDATA[Pakettitel]]></de>
<en><![CDATA[Package title]]></en>
</locale>
</groups>
</locales>Use CDATA for translation text. This avoids XML escaping problems when the translation contains punctuation, placeholders, or markup.
Locale Groups
Use one group per package and data target.
<groups name="quiqqer/bricks" datatype="php,js">
<locale name="package.title">
<de><![CDATA[QUIQQER - Baustein Modul / Bricks]]></de>
<en><![CDATA[QUIQQER - Bricks Module]]></en>
</locale>
</groups>The datatype attribute controls where translations are available:
| Value | Use |
|---|---|
php | PHP/runtime translations. |
js | JavaScript translations. |
php,js | Translations needed in both PHP and JavaScript. |
Choose the narrowest target that fits the usage. Backend JavaScript labels need js or php,js; server-side exceptions and mail texts can stay PHP-only.
Naming Translation Keys
Use descriptive names that match the feature area.
Common patterns:
package.titlepackage.descriptionpermission.vendor.package.actionexception.feature.reasonmessage.feature.resultconsole.ToolName.descconsole.ToolName.help.argumentName
Examples:
<locale name="permission.quiqqer.bricks.create">
<de><![CDATA[Darf Bausteine erstellen.]]></de>
<en><![CDATA[Can create blocks.]]></en>
</locale>
<locale name="brick.content.title">
<de><![CDATA[Bausteine: Inhalt]]></de>
<en><![CDATA[Bricks: Content]]></en>
</locale>Placeholders
Translations can contain placeholders in square brackets. Pass replacement values when reading the translation.
<locale name="message.brick.saved">
<de><![CDATA[Baustein [brickId] wurde gespeichert.]]></de>
<en><![CDATA[Brick [brickId] was saved.]]></en>
</locale>$message = QUI::getLocale()->get('vendor/package', 'message.brick.saved', [
'brickId' => $brickId
]);HTML Text
Use html="true" when a translation intentionally contains HTML.
<locale name="message.address.invalid" html="true">
<de><![CDATA[Bitte füllen Sie <strong>[field]</strong> aus.]]></de>
<en><![CDATA[Please fill in <strong>[field]</strong>.]]></en>
</locale>Only use HTML translations where the rendering context expects HTML. Do not use HTML translations for plain CLI output, log messages, or attributes.
Read Translations In PHP
Use QUI::getLocale()->get() for the current runtime language.
$title = QUI::getLocale()->get('vendor/package', 'package.title');Pass placeholders as the third argument:
$text = QUI::getLocale()->get('vendor/package', 'message.brick.saved', [
'brickId' => $brickId
]);Use getByLang() when code needs translations for a specific language, for example when creating default records for all available languages.
$title = QUI::getLocale()->getByLang($language, 'vendor/package', 'package.title');Read Translations In JavaScript
Use the Locale module in browser code.
require(['Locale'], function (Locale) {
const title = Locale.get('vendor/package', 'package.title');
});Pass replacements as an object:
Locale.get('vendor/package', 'message.brick.saved', {
brickId: brickId
});Use Translations In XML
Package metadata can reference locale entries instead of hard-coding text.
<title>
<locale group="vendor/package" var="package.title"/>
</title>This pattern is common in package.xml for package titles and descriptions.
Use Translations In Templates
Smarty templates can use the locale function.
{locale group="vendor/package" var="package.title"}Practical Checklist
Before adding translations:
- Use the package name as locale group.
- Keep keys descriptive and grouped by feature area.
- Use
php,js, orphp,jsbased on actual usage. - Add all languages supported by the package.
- Use placeholders instead of concatenating translated sentences.
- Mark HTML translations with
html="true"only when HTML is intended. - Reuse the same locale keys in PHP, JavaScript, XML, and templates where they describe the same text.
