The Translatable decorator allows your DataObjects to have versions in different languages, defining which fields are can be translated. Translatable can be applied to any {@link DataObject} subclass, but is mostly used with {@link SiteTree}.

Translatable is compatible with the extension.
To avoid cluttering up the database-schema of the 99% of sites without multiple languages,
the translation-feature is disabled by default.
Locales (e.g. 'en_US') are used in Translatable for identifying a record by language,
see section "Locales and Language Tags".
The extension is automatically enabled for SiteTree and SiteConfig records,
if they can be found. Add the following to your config.yml in order to
register a custom class:
Make sure to rebuild the database through /dev/build after enabling translatable.
Use the correct before building the database
for the first time, as this locale will be written on all new records.
<h3>"Default" locales</h3>
Important: If the "default language" of your site is not US-English (en_US),
please ensure to set the appropriate default language for
your content before building the database with Translatable enabled:
Translatable::set_default_locale(<locale>); // e.g. 'de_DE' or 'fr_FR'
For the Translatable class, a "locale" consists of a language code plus a region
code separated by an underscore,
for example "de_AT" for German language ("de") in the region Austria ("AT").
See http://www.w3.org/International/articles/language-tags/ for a detailed description.
Getting a translation for an existing instance:
$translatedObj = Translatable::get_one_by_locale('MyObject', 'de_DE');
Getting a translation for an existing instance:
$obj = DataObject::get_by_id('MyObject', 99); // original language
$translatedObj = $obj->getTranslation('de_DE');
Getting translations through .
This is *not* a recommended approach, but sometimes inavoidable (e.g. for methods).
$origLocale = Translatable::get_current_locale();
$obj = Versioned::get_one_by_stage('MyObject', "ID = 99");
Creating a translation:
$obj = new MyObject();
$translatedObj = $obj->createTranslation('de_DE');
<h2>Usage for SiteTree</h2>
Translatable can be used for subclasses of ,
it is automatically configured if this class is foun.
If a child page translation is requested without the parent
page already having a translation in this language, the extension
will recursively create translations up the tree.
Caution: The "URLSegment" property is enforced to be unique across
languages by auto-appending the language code at the end.
You'll need to ensure that the appropriate "reading language" is set
before showing links to other pages on a website through $_GET['locale'].
Pages in different languages can have different publication states
through the extension.
Note: You can't get Children() for a parent page in a different language
through set_current_locale(). Get the translated parent first.
// wrong
// right
$germanParent = $englishParent->getTranslation('de_DE');
<h2>Translation groups</h2>
Each translation can have one or more related pages in other languages.
This relation is optional, meaning you can
create translations which have no representation in the "default language".
This means you can have a french translation with a german original,
without either of them having a representation
in the default english language tree.
Caution: There is no versioning for translation groups,
meaning associating an object with a group will affect both stage and live records.
SiteTree database table (abbreviated)
^ ID ^ URLSegment ^ Title ^ Locale ^
| 1 | about-us | About us | en_US |
| 2 | ueber-uns | Über uns | de_DE |
| 3 | contact | Contact | en_US |
SiteTree_translationgroups database table
^ TranslationGroupID ^ OriginalID ^
| 99 | 1 |
| 99 | 2 |
| 199 | 3 |
<h2>Character Sets</h2>
Caution: Does not apply any character-set conversion, it is assumed that all content
is stored and represented in UTF-8 (Unicode). Please make sure your database and
HTML-templates adjust to this.
Authors without administrative access need special permissions to edit locales other than
the default locale.
- TRANSLATE_ALL: Translate into all locales
- Translate_<locale>: Translate a specific locale. Only available for all locales set in
Note: If user-specific view permissions are required, please overload `SiteTree->canView()`.
Disabling Translatable after creating translations will lead to all
pages being shown in the default sitetree regardless of their language.
It is advised to start with a new database after uninstalling Translatable,
or manually filter out translated objects through their "Locale" property
in the database.


class Translatable extends DataExtension implements PermissionProvider {
  • // constants
  • const QUERY_LOCALE_FILTER_ENABLED = 'Translatable.LocaleFilterEnabled';



  • DataExtension


  • PermissionProvider


Line Task
252+ Re-implement cookie and member option
555 Disabled selection of translatable fields - we're setting all fields as
702+ Find more appropriate place to hook into database building
703 This relies on the Locale attribute being on the base data class, and not any subclasses
980 Coupling to Versioned, we need to avoid removing
1052+ This is specific to SiteTree and CMSMain
1052+ Implement a special "translation mode" which triggers display of the
1235+ Integrate with blacklist once branches/translatable is merged back.


Name Value
QUERY_LOCALE_FILTER_ENABLED 'Translatable.LocaleFilterEnabled'



  • $enforce_global_unique_urls — boolean
  • $translate_excluded_fields — array
    Exclude these fields from translation


  • $allowed_locales — array
  • $current_locale — string
    The language in which we are reading dataobjects.
  • $default_locale — string
    The 'default' language.
  • $locale_filter_enabledbool
    If this is set to TRUE then {@link augmentSQL()} will automatically add a filter clause to limit queries to the current {@link get_current_locale()}. This camn be disabled using {@link disable_locale_filter()}
  • $original_values — array
    A map of the field values of the original (untranslated) DataObject record
  • $tableList — mixed
    A cached list of existing tables
  • $translatableFields — array
    An array of fields that can be translated.


  • $enable_siteconfig_generation — boolean
    Enables automatic population of SiteConfig fields using createTranslation if created outside of the Translatable module



  • addTranslatableFields() — This method can be called multiple times on the same FieldList because it checks which fields have already been added or modified.
  • filtersOnLocale() — Check if a given SQLQuery filters on the Locale field
  • populateSiteConfigDefaults() — When the SiteConfig object is automatically instantiated, we should ensure that 1. All SiteConfig objects belong to the same group 2. Defaults are correctly initiated from the base object 3. The creation mechanism uses the createTranslation function in order to be consistent This function ensures that any already created "vanilla" SiteConfig object is populated correctly with translated values.