Locales
PILOS supports multiple languages, with English and German officially maintained.
English serves as the reference language and can only be changed in the source code.
All translations are managed in the POEditor Project. To contribute, join the project.
Locale structure
Locales are stored as php arrays in the lang folder.
Each locale has its own subdirectory named after the locale code (e.g. en).
Within the directory each group has its own file (part before the first dot in the translation string), e.g. 'app' or 'auth'.
For example, the string auth.ldap.username_help would be stored in the file auth.php.
Within the file, the keys are organized in nested php arrays.
Placeholders
Placeholders in localization strings are defined using the :placeholder syntax.
DO NOT use :n and :count as these are reserved for pluralization.
For example:
"Welcome, :name!"
Both frontend and backend code can replace :name with a dynamic value, producing:
"Welcome, John!"
The capitalization of a placeholder controls how the replacement value is inserted.
If the placeholder is written in lowercase, the value is inserted without modification.
For example, given the replacement value John:
"Welcome, :name!" // Welcome, John!
If the first letter of the placeholder is uppercase, the first letter of the value is converted to uppercase.
For example, given the replacement value john:
"Welcome, :Name!" // Welcome, John!
If the entire placeholder is uppercase, the entire value is converted to uppercase.
For example, given the replacement value john:
"Welcome, :NAME!" // Welcome, JOHN!
When translating, ensure that placeholder names remain unchanged and are correctly positioned within the sentence structure of the target language. Only adjust their capitalization if the replacement value should be transformed accordingly.
Pluralization
Pluralization can be complex, and we currently support a subset of the flexible pluralization format used by Laravel.
Format
{0} No items |{1} One item |[2,*] :count items
Each plural form is separated by a pipe (|):
- Curly braces
{}define exact numbers. - Square brackets
[]define numeric ranges. - The asterisk (
*) denotes an open upper / lower range.
Pluralization forms must be listed in ascending order, and you can define as many as required for a given locale.
Overriding locales
You can override the default locales by creating custom locale files in the resources/custom/lang directory.
This directory needs to be mounted to the container by adjusting the docker-compose file.
- "./resources/custom:/var/www/html/resources/custom"
The locales are merged during runtime, so you only need to define the keys you want to override.
Example
To override the LDAP username help text in the english locale, create a custom locale file resources/custom/lang/en/auth.php:
<?php
return [
'ldap' => [
'username_help' => 'My custom help text'
]
];
To customize the date time format and the display name of a locale create a json file metadata.json in the locales directory.
{
"name": "German",
"dateTimeFormat": {
"dateShort": {
"year": "numeric",
"month": "2-digit",
"day": "2-digit"
},
"dateLong": {
"year": "numeric",
"month": "short",
"day": "2-digit"
},
"time": {
"hour": "2-digit",
"minute": "2-digit",
"hour12": false
},
"datetimeShort": {
"year": "numeric",
"month": "2-digit",
"day": "2-digit",
"hour": "2-digit",
"minute": "2-digit",
"hour12": false
},
"datetimeLong": {
"year": "numeric",
"month": "short",
"day": "2-digit",
"hour": "2-digit",
"minute": "2-digit",
"hour12": false
}
}
}
New locales
To add custom locales that are not part of the core, add them to the resources/custom/lang directory.
This directory need to be mounted to the container by adjusting the docker-compose file.
- "./resources/custom:/var/www/html/resources/custom"
You need to create all php files and metadata.json file.
Any missing keys will be filled with the default english translation.
To enable the new locale, you need to add it to the ENABLED_LOCALES in the .env file.
Locale caching
For better performance, locales are automatically cached in production when the container is started.
To manually cache the locales, run the following command:
docker compose exec app pilos-cli locales:cache