Internationalization
Note: This covers how to translate Concrete CMS's interface itself. For help with running the content of your site in multiple languages, check out multi-lingual in our Editors guide.
Translation Files
Translation File Types
Concrete installations support multiple language files: - Core translations - Package translations - Site translations
Translation File Precedence
- Core translations are overridden by package and site translations.
- Package translations are overridden by site translations.
Core and Package Translation Updates
Update core and package translations via /dashboard/system/basics/multilingual/update or c5:install-language CLI command. Community contributions are sourced from translate.concretecms.org.
Managing Site Translations
Manage via /dashboard/system/multilingual/translate_interface. Use "Reload Strings" to extract and translate strings, which include:
- Site name
- Strings in t()/tc()/t2() in PHP files from various directories:
- /application/blocks
- /application/elements
- /application/controllers
- /application/mail
- /application/page_types
- /application/single_pages
- /application/themes
- /application/views
- /application/src
- Names of block templates in /application/blocks and /application/themes
- Names of theme presets in /application/themes
- Strings from getTranslatableStrings in package controllers
- Names of defined areas, attribute keys, key categories, sets, types, authentication types
- Names and descriptions of user groups, group sets, job sets
- Permission access entity types, keys, key categories
- Select attribute value options
- Names of Concrete trees and notes
Overriding Core and Package Translations
Override core or package strings by creating a PHP file in /application/src. For example:
<?php
defined('C5_EXECUTE') or die('Access Denied.');
return;
t('String');
Localization
Introduction
Localization primarily involves the t() function. It translates strings like:
<button><?php echo t('Cancel'); ?></button>
Cancel is automatically translated to the user's language.
Parameters
Dynamic content in strings requires careful translation. For example, with $blockTypeName:
Incorrect:
echo t('Edit '.$blockTypeName);
Also incorrect:
echo t('Edit').' '.$blockTypeName;
Correct:
echo t('Edit %s', $blockTypeName);
or
echo sprintf(t('Edit %s'), $blockTypeName);
For multiple variables, use numbered arguments for correct order:
echo t('Posted by %1$s on %2$s', $user, $date);
Include comments for context:
echo t(/*i18n %1$s is a user name, %2$s is a date/time*/'Posted by %1$s at %2$s', $user, $date);
t2() Function
For pluralization, use t2() instead of t():
echo t2('%d page', '%d pages', $pages);
tc() Function
To handle multiple meanings, use tc() with context:
echo tc('A group of items', 'Set');
echo tc('Apply a value to an option', 'Set');
Core Contexts
Concrete includes core contexts like AreaName, AttributeKeyName, BlockTypeSetName, etc., for accurate translation.
Dates and Times
Use the Date helper for localized dates:
$dateHelper = \Core::make('helper/date');
echo $dateHelper->date('F');
Use specific methods for formatting dates and times, not the PHP date() function.
Translating Packages
For package localization:
1. Extract strings using concrete5 c5:package-translate.
2. Create .po and .mo files for each language.
3. Translate .po files.
4. Compile to .mo with concrete5 c5:package-translate or c5:package-pack.
Example command:
concrete5 c5:package-translate handyman -l it_IT -l de_DE
Translators then work on .po files, and the files are compiled into .mo.