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". <h2>Configuration</h2> 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: <code> MyClass: extensions: Translatable </code> 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: <code> Translatable::set_default_locale(<locale>); // e.g. 'de_DE' or 'fr_FR' </code> 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. <h2>Usage</h2> Getting a translation for an existing instance: <code> $translatedObj = Translatable::get_one_by_locale('MyObject', 'de_DE'); </code> Getting a translation for an existing instance: <code> $obj = DataObject::get_by_id('MyObject', 99); // original language $translatedObj = $obj->getTranslation('de_DE'); </code> Getting translations through . This is *not* a recommended approach, but sometimes inavoidable (e.g. for methods). <code> $origLocale = Translatable::get_current_locale(); Translatable::set_current_locale('de_DE'); $obj = Versioned::get_one_by_stage('MyObject', "ID = 99"); Translatable::set_current_locale($origLocale); </code> Creating a translation: <code> $obj = new MyObject(); $translatedObj = $obj->createTranslation('de_DE'); </code> <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. <code> // wrong Translatable::set_current_locale('de_DE'); $englishParent->Children(); // right $germanParent = $englishParent->getTranslation('de_DE'); $germanParent->Children(); </code> <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. <h2>Permissions</h2> 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 `Translatable::set_allowed_locales()`. Note: If user-specific view permissions are required, please overload `SiteTree->canView()`. <h2>Uninstalling/Disabling</h2> 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.
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
985
Coupling to Versioned, we need to avoid removing
1057+
This is specific to SiteTree and CMSMain
1057+
Implement a special "translation mode" which triggers display of the readonly fields, so you can translation INTO the "default language" while seeing readonly fields as well.
1240+
Integrate with blacklist once branches/translatable is merged back.
Constants
Name
Value
QUERY_LOCALE_FILTER_ENABLED
'Translatable.LocaleFilterEnabled'
Members
private
$enforce_global_unique_urls
—
boolean
$translate_excluded_fields
—
array Exclude these fields from translation
protected
$allowed_locales
—
array
$current_locale
—
string The language in which we are reading dataobjects.
$default_locale
—
string The 'default' language.
$locale_filter_enabled
—
bool 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.
public
$enable_siteconfig_generation
—
boolean Enables automatic population of SiteConfig fields using createTranslation if created outside of the Translatable module
Methods
protected
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.
public
__construct()
— Construct a new Translatable object.
MetaTags()
— Returns <link rel="alternate"> markup for insertion into a HTML4/XHTML compliant <head> section, listing all available translations of a page.
addTranslationGroup()
— Add a record to a "translation group", so its relationship to other translations based off the same object can be determined later on.
alternateGetByLink()
— Attempt to get the page for a link in the default language that has been translated.
augmentDatabase()
— Create <table>_translation database table to enable tracking of "translation groups" in which each related translation of an object acts as a sibling, rather than a parent->child relation.
augmentSQL()
— Changes any SELECT query thats not filtering on an ID to limit by the current language defined in {@link get_current_locale()}.
augmentValidURLSegment()
— Extends the SiteTree::validURLSegment() method, to do checks appropriate to Translatable
baseTable()
— Return the base table - the class that directly extends DataObject.
cacheKeyComponent()
— Return a piece of text to keep DataObject cache keys appropriately specific
enable_locale_filter()
— Enables automatic filtering by locale. This is normally called after is has been disabled using {@link disable_locale_filter()}.
getTranslations()
— Gets all related translations for the current object, excluding itself. See {@link getTranslation()} to retrieve a single translated object.
get_allowed_locales()
— Get all locales which are generally permitted to be translated.
get_homepage_link_by_locale()
— Get the RelativeLink value for a home page in another locale. This is found by searching for the default home page in the default language, then returning the link to the translated version (if one exists).
isTranslation()
— Determines if the record has a locale, and if this locale is different from the "default locale" set in {@link Translatable::default_locale()}.
isVersionedTable()
— Determine if a table needs Versioned support This is called at db/build time
onBeforeDelete()
— Remove the record from the translation group mapping.
onBeforeWrite()
— Recursively creates translations for parent pages in this language if they aren't existing already. This is a necessity to make nested pages accessible in a translated CMS page tree.
populateDefaults()
— Hooks into the DataObject::populateDefaults() method
set_allowed_locales()
— Define all locales which in which a new translation is allowed.
set_current_locale()
— Set the reading language, either namespaced to 'site' (website content) or 'cms' (management backend). This value is used in {@link augmentSQL()} to "auto-filter" all SELECT queries by this language.
set_default_locale()
— Set default language. Please set this value *before* creating any database records (like pages), as this locale will be attached to all new records.
updateCMSFields()
— If the record is not shown in the default language, this method will try to autoselect a master language which is shown alongside the normal formfields as a readonly representation.