Internationalization

Improvements?

Let us know by posting here.

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.