mirror of
https://github.com/silverstripe/silverstripe-translatable
synced 2024-10-22 09:05:59 +00:00
Merge remote-tracking branch 'origin/2.1'
# Conflicts: # .travis.yml # README.md # code/model/Translatable.php # composer.json
This commit is contained in:
commit
fcabda4188
@ -1,11 +1,10 @@
|
|||||||
# Translatable module for SilverStripe CMS #
|
# Translatable module for SilverStripe CMS #
|
||||||
|
|
||||||
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-translatable.png)](http://travis-ci.org/silverstripe/silverstripe-translatable)
|
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-translatable.png?branch=2.1)](http://travis-ci.org/silverstripe/silverstripe-translatable)
|
||||||
|
|
||||||
## Introduction ##
|
## Introduction ##
|
||||||
|
|
||||||
Allows translation of DataObject and SiteTree records into multiple languages.
|
Allows translation of DataObject and SiteTree records into multiple languages.
|
||||||
Note: This module was originally part of the SilverStripe CMS 2.x codebase.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -561,10 +561,10 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
if($this->owner && $this->translatableFields === null) {
|
if($this->owner && $this->translatableFields === null) {
|
||||||
$this->translatableFields = array_merge(
|
$this->translatableFields = array_merge(
|
||||||
array_keys($this->owner->db()),
|
array_keys($this->owner->db()),
|
||||||
array_keys($this->owner->has_many()),
|
array_keys($this->owner->hasMany()),
|
||||||
array_keys($this->owner->many_many())
|
array_keys($this->owner->manyMany())
|
||||||
);
|
);
|
||||||
foreach (array_keys($this->owner->has_one()) as $fieldname) {
|
foreach (array_keys($this->owner->hasOne()) as $fieldname) {
|
||||||
$this->translatableFields[] = $fieldname.'ID';
|
$this->translatableFields[] = $fieldname.'ID';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -582,6 +582,30 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given SQLQuery filters on the Locale field
|
||||||
|
*
|
||||||
|
* @param SQLQuery $query
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected function filtersOnLocale($query) {
|
||||||
|
foreach($query->getWhere() as $condition) {
|
||||||
|
// Compat for 3.1/3.2 where syntax
|
||||||
|
if(is_array($condition)) {
|
||||||
|
// In >=3.2 each $condition is a single length array('condition' => array('params'))
|
||||||
|
reset($condition);
|
||||||
|
$condition = key($condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
// >=3.2 allows conditions to be expressed as evaluatable objects
|
||||||
|
if(interface_exists('SQLConditionGroup') && ($condition instanceof SQLConditionGroup)) {
|
||||||
|
$condition = $condition->conditionSQL($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(preg_match('/("|\'|`)Locale("|\'|`)/', $condition)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes any SELECT query thats not filtering on an ID
|
* Changes any SELECT query thats not filtering on an ID
|
||||||
* to limit by the current language defined in {@link get_current_locale()}.
|
* to limit by the current language defined in {@link get_current_locale()}.
|
||||||
@ -666,7 +690,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
/**
|
/**
|
||||||
* @todo Find more appropriate place to hook into database building
|
* @todo Find more appropriate place to hook into database building
|
||||||
*/
|
*/
|
||||||
function requireDefaultRecords() {
|
public function requireDefaultRecords() {
|
||||||
// @todo This relies on the Locale attribute being on the base data class, and not any subclasses
|
// @todo This relies on the Locale attribute being on the base data class, and not any subclasses
|
||||||
if($this->owner->class != ClassInfo::baseDataClass($this->owner->class)) return false;
|
if($this->owner->class != ClassInfo::baseDataClass($this->owner->class)) return false;
|
||||||
|
|
||||||
@ -699,7 +723,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
))->column();
|
))->column();
|
||||||
if(!$idsWithoutLocale) return;
|
if(!$idsWithoutLocale) return;
|
||||||
|
|
||||||
if(class_exists('SiteTree') && $this->owner->class == 'SiteTree') {
|
if(class_exists('SiteTree') && $this->owner->class == 'SiteTree') {
|
||||||
foreach(array('Stage', 'Live') as $stage) {
|
foreach(array('Stage', 'Live') as $stage) {
|
||||||
foreach($idsWithoutLocale as $id) {
|
foreach($idsWithoutLocale as $id) {
|
||||||
$obj = Versioned::get_one_by_stage(
|
$obj = Versioned::get_one_by_stage(
|
||||||
@ -707,7 +731,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
$stage,
|
$stage,
|
||||||
sprintf('"SiteTree"."ID" = %d', $id)
|
sprintf('"SiteTree"."ID" = %d', $id)
|
||||||
);
|
);
|
||||||
if(!$obj) continue;
|
if(!$obj || $obj->ObsoleteClassName) continue;
|
||||||
|
|
||||||
$obj->Locale = Translatable::default_locale();
|
$obj->Locale = Translatable::default_locale();
|
||||||
|
|
||||||
@ -724,7 +748,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
} else {
|
} else {
|
||||||
foreach($idsWithoutLocale as $id) {
|
foreach($idsWithoutLocale as $id) {
|
||||||
$obj = DataObject::get_by_id($this->owner->class, $id);
|
$obj = DataObject::get_by_id($this->owner->class, $id);
|
||||||
if(!$obj) continue;
|
if(!$obj || $obj->ObsoleteClassName) continue;
|
||||||
|
|
||||||
$obj->Locale = Translatable::default_locale();
|
$obj->Locale = Translatable::default_locale();
|
||||||
$obj->write();
|
$obj->write();
|
||||||
@ -1446,6 +1470,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
|
|
||||||
$newTranslation->ID = 0;
|
$newTranslation->ID = 0;
|
||||||
$newTranslation->Locale = $locale;
|
$newTranslation->Locale = $locale;
|
||||||
|
$newTranslation->Version = 0;
|
||||||
|
|
||||||
$originalPage = $this->getTranslation(self::default_locale());
|
$originalPage = $this->getTranslation(self::default_locale());
|
||||||
if ($originalPage) {
|
if ($originalPage) {
|
||||||
@ -1458,7 +1483,7 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
if(Config::inst()->get('Translatable', 'enforce_global_unique_urls')) {
|
if(Config::inst()->get('Translatable', 'enforce_global_unique_urls')) {
|
||||||
$newTranslation->URLSegment = $urlSegment . '-' . i18n::convert_rfc1766($locale);
|
$newTranslation->URLSegment = $urlSegment . '-' . i18n::convert_rfc1766($locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hacky way to set an existing translation group in onAfterWrite()
|
// hacky way to set an existing translation group in onAfterWrite()
|
||||||
$translationGroupID = $this->getTranslationGroup();
|
$translationGroupID = $this->getTranslationGroup();
|
||||||
$newTranslation->_TranslationGroupID = $translationGroupID ? $translationGroupID : $this->owner->ID;
|
$newTranslation->_TranslationGroupID = $translationGroupID ? $translationGroupID : $this->owner->ID;
|
||||||
@ -1810,11 +1835,13 @@ class Translatable extends DataExtension implements PermissionProvider {
|
|||||||
$IDFilter = ($this->owner->ID) ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null;
|
$IDFilter = ($this->owner->ID) ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null;
|
||||||
$parentFilter = null;
|
$parentFilter = null;
|
||||||
|
|
||||||
|
if (Config::inst()->get('SiteTree', 'nested_urls')) {
|
||||||
if($this->owner->ParentID) {
|
if($this->owner->ParentID) {
|
||||||
$parentFilter = " AND \"SiteTree\".\"ParentID\" = {$this->owner->ParentID}";
|
$parentFilter = " AND \"SiteTree\".\"ParentID\" = {$this->owner->ParentID}";
|
||||||
} else {
|
} else {
|
||||||
$parentFilter = ' AND "SiteTree"."ParentID" = 0';
|
$parentFilter = ' AND "SiteTree"."ParentID" = 0';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$existingPage = SiteTree::get()
|
$existingPage = SiteTree::get()
|
||||||
// disable get_one cache, as this otherwise may pick up results from when locale_filter was on
|
// disable get_one cache, as this otherwise may pick up results from when locale_filter was on
|
||||||
|
@ -128,6 +128,37 @@ See http://www.w3.org/International/articles/language-tags/ for a detailed descr
|
|||||||
|
|
||||||
To ensure that your template declares the correct content language, please see [i18n](i18n#declaring_the_content_language_in_html).
|
To ensure that your template declares the correct content language, please see [i18n](i18n#declaring_the_content_language_in_html).
|
||||||
|
|
||||||
|
### User Permissions
|
||||||
|
|
||||||
|
Permissions to view and create translations are managed through the CMS, based on security groups
|
||||||
|
defined in the "Security" section (`admin/security`). By default, all CMS users with rights to create and edit pages
|
||||||
|
can also create translations. This can be restricted by removing the "Translate into all available languages" permission,
|
||||||
|
and replacing it with language specific permissions.
|
||||||
|
|
||||||
|
You can further restrict viewing and editing rights on a specific language through the "Settings" section (`admin/settings`).
|
||||||
|
Each language has its own configuration "translation", and you can configure access to groups there.
|
||||||
|
|
||||||
|
Here's an example setup which allows content authors to write only English master content,
|
||||||
|
while translators can only write German translations, but still see readonly versions of the English master content.
|
||||||
|
|
||||||
|
Group: Administrator
|
||||||
|
|
||||||
|
* Has "Full administrative rights" permission
|
||||||
|
|
||||||
|
Group: Content Author English
|
||||||
|
|
||||||
|
* Has "View language dropdown" permission
|
||||||
|
* Has "Translate into English" permission
|
||||||
|
* Is part of "Who can edit pages?" in "Settings" for "English"
|
||||||
|
* Is part of "Who can create pages?" in "Settings" for "English"
|
||||||
|
|
||||||
|
Group: Translator German
|
||||||
|
|
||||||
|
* Has "View language dropdown" permission
|
||||||
|
* Has "Translate into German" permission
|
||||||
|
* Is part of "Who can edit pages?" in "Settings" for "German"
|
||||||
|
* Is part of "Who can create pages?" in "Settings" for "German"
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
Getting a translation for an existing instance:
|
Getting a translation for an existing instance:
|
||||||
|
22
lang/eo.yml
Normal file
22
lang/eo.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
eo:
|
||||||
|
CMSMain:
|
||||||
|
LANGUAGEDROPDOWNLABEL: Lingvo
|
||||||
|
CMSMain_left:
|
||||||
|
GO: Ek
|
||||||
|
Form:
|
||||||
|
LANGAOTHER: 'Aliaj lingvoj'
|
||||||
|
LANGAVAIL: 'Disponeblaj lingvoj'
|
||||||
|
Translatable:
|
||||||
|
ALLCREATED: 'Kreis ĉiujn permesitajn tradukojn.'
|
||||||
|
CREATE: 'Krei novan tradukon'
|
||||||
|
CREATEBUTTON: Krei
|
||||||
|
EXISTING: 'Ekzistantaj tradukoj'
|
||||||
|
NEWLANGUAGE: 'Nova lingvo'
|
||||||
|
NOTICENEWPAGE: 'Bonvole konservu ĉi tiun paĝon antaŭ ol krei tradukon'
|
||||||
|
TRANSLATEALLPERMISSION: 'Traduki en ĉiujn disponeblajn lingvojn'
|
||||||
|
TRANSLATEPERMISSION: 'Tradukti je %s'
|
||||||
|
TRANSLATEVIEWLANGS: 'Vidigi lingvan falliston'
|
||||||
|
TRANSLATIONS: Tradukoj
|
||||||
|
Translatable_Transform:
|
||||||
|
OriginalCheckboxLabel: 'Origina: {value}'
|
||||||
|
OriginalFieldLabel: 'Origina: {title}'
|
14
lang/id.yml
Normal file
14
lang/id.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
id:
|
||||||
|
CMSMain:
|
||||||
|
LANGUAGEDROPDOWNLABEL: Bahasa
|
||||||
|
CMSMain_left:
|
||||||
|
GO: Lanjut
|
||||||
|
Form:
|
||||||
|
LANGAOTHER: 'Bahasa lain'
|
||||||
|
LANGAVAIL: 'Bahasa yang tersedia'
|
||||||
|
Translatable:
|
||||||
|
CREATE: 'Buat terjemahan baru'
|
||||||
|
CREATEBUTTON: Buat
|
||||||
|
EXISTING: 'Terjemahan yang ada'
|
||||||
|
NEWLANGUAGE: 'Bahasa baru'
|
||||||
|
TRANSLATEPERMISSION: 'Terjemahan %s'
|
@ -5,13 +5,18 @@ nl:
|
|||||||
GO: Gaan
|
GO: Gaan
|
||||||
Form:
|
Form:
|
||||||
LANGAOTHER: 'Overige talen'
|
LANGAOTHER: 'Overige talen'
|
||||||
|
LANGAVAIL: 'Beschikbare talen'
|
||||||
Translatable:
|
Translatable:
|
||||||
ALLCREATED: 'Alle beschikbare vertalingen zijn aangemaakt'
|
ALLCREATED: 'Alle toegelaten vertalingen zijn aangemaakt. '
|
||||||
CREATE: 'Voeg nieuwe vertaling toe'
|
CREATE: 'Voeg nieuwe vertaling toe'
|
||||||
CREATEBUTTON: Toevoegen
|
CREATEBUTTON: Toevoegen
|
||||||
EXISTING: 'Bestaande vertalingen'
|
EXISTING: 'Bestaande vertalingen'
|
||||||
NEWLANGUAGE: 'Nieuwe taal'
|
NEWLANGUAGE: 'Nieuwe taal'
|
||||||
NOTICENEWPAGE: 'Sla deze pagina op voordat u een nieuwe vertaling toevoegd'
|
NOTICENEWPAGE: 'Sla deze pagina op voor u een nieuwe vertaling toevoegt'
|
||||||
TRANSLATEALLPERMISSION: 'Vertaal in alle beschikbare talen'
|
TRANSLATEALLPERMISSION: 'Vertaal in alle beschikbare talen'
|
||||||
TRANSLATEPERMISSION: 'Vertaal %s'
|
TRANSLATEPERMISSION: 'Vertaal %s'
|
||||||
|
TRANSLATEVIEWLANGS: 'Toon dropdown met talen'
|
||||||
TRANSLATIONS: Vertalingen
|
TRANSLATIONS: Vertalingen
|
||||||
|
Translatable_Transform:
|
||||||
|
OriginalCheckboxLabel: 'Origineel: {value}'
|
||||||
|
OriginalFieldLabel: 'Originele {title}'
|
||||||
|
20
lang/pl.yml
Normal file
20
lang/pl.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
pl:
|
||||||
|
CMSMain:
|
||||||
|
LANGUAGEDROPDOWNLABEL: Język
|
||||||
|
CMSMain_left:
|
||||||
|
GO: Przejdź
|
||||||
|
Form:
|
||||||
|
LANGAOTHER: 'Inne języki'
|
||||||
|
LANGAVAIL: 'Dostępne języki'
|
||||||
|
Translatable:
|
||||||
|
ALLCREATED: 'Wszystkie dozwolone tłumaczenia zostały stworzone.'
|
||||||
|
CREATE: 'Stwórz nowe tłumaczenie'
|
||||||
|
CREATEBUTTON: Stwórz
|
||||||
|
EXISTING: 'Istniejące tłumaczenia'
|
||||||
|
NEWLANGUAGE: 'Nowy język'
|
||||||
|
NOTICENEWPAGE: 'Zapisz tą stronę zanim ją przetłumaczysz'
|
||||||
|
TRANSLATEPERMISSION: 'Tłumaczenie %s'
|
||||||
|
TRANSLATIONS: Tłumaczenia
|
||||||
|
Translatable_Transform:
|
||||||
|
OriginalCheckboxLabel: 'Oryginalny: {value}'
|
||||||
|
OriginalFieldLabel: 'Oryginalny: {title}'
|
@ -12,7 +12,11 @@ pl_PL:
|
|||||||
CREATEBUTTON: Stwórz
|
CREATEBUTTON: Stwórz
|
||||||
EXISTING: 'Istniejące tłumaczenia'
|
EXISTING: 'Istniejące tłumaczenia'
|
||||||
NEWLANGUAGE: 'Nowy język'
|
NEWLANGUAGE: 'Nowy język'
|
||||||
NOTICENEWPAGE: 'Zapisz stronę przet stworzeniem tłumaczenia'
|
NOTICENEWPAGE: 'Zapisz stronę przed stworzeniem tłumaczenia'
|
||||||
TRANSLATEALLPERMISSION: 'Przetłumacz na wszystkie dostępne języki'
|
TRANSLATEALLPERMISSION: 'Przetłumacz na wszystkie dostępne języki'
|
||||||
TRANSLATEPERMISSION: 'Tłumacz %s'
|
TRANSLATEPERMISSION: 'Tłumacz %s'
|
||||||
|
TRANSLATEVIEWLANGS: 'Pokaż listę rozwijaną języka'
|
||||||
TRANSLATIONS: Tłumaczenia
|
TRANSLATIONS: Tłumaczenia
|
||||||
|
Translatable_Transform:
|
||||||
|
OriginalCheckboxLabel: 'Oryginalny: {value}'
|
||||||
|
OriginalFieldLabel: 'Oryginalny {title}'
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
sr@latin:
|
|
||||||
CMSMain:
|
|
||||||
LANGUAGEDROPDOWNLABEL: Jezik
|
|
||||||
CMSMain_left:
|
|
||||||
GO: Idi
|
|
||||||
Form:
|
|
||||||
LANGAOTHER: 'Drugi jezici'
|
|
||||||
LANGAVAIL: 'Raspoloživi jezici'
|
|
||||||
Translatable:
|
|
||||||
ALLCREATED: 'Svi dozvoljeni prevodi su kreirani.'
|
|
||||||
CREATE: 'Kreiraj novi prevod'
|
|
||||||
CREATEBUTTON: Kreiraj
|
|
||||||
EXISTING: 'Postojeći prevodi'
|
|
||||||
NEWLANGUAGE: 'Novi jezik'
|
|
||||||
NOTICENEWPAGE: 'Molimo Vas da pre kreiranja prevoda snimite stranicu'
|
|
||||||
TRANSLATEALLPERMISSION: 'Prevedi na sve raspoložive jezike'
|
|
||||||
TRANSLATEPERMISSION: 'Prevedi %s'
|
|
||||||
TRANSLATEVIEWLANGS: 'Pogledaj padajući meni za izbor jezika'
|
|
||||||
TRANSLATIONS: Prevodi
|
|
||||||
Translatable_Transform:
|
|
||||||
OriginalCheckboxLabel: 'Original: {value}'
|
|
||||||
OriginalFieldLabel: 'Original {title}'
|
|
Loading…
x
Reference in New Issue
Block a user