diff --git a/code/model/Translatable.php b/code/model/Translatable.php index e4128ab..5e644d4 100755 --- a/code/model/Translatable.php +++ b/code/model/Translatable.php @@ -204,6 +204,13 @@ class Translatable extends DataExtension implements PermissionProvider { * common locales. */ protected static $allowed_locales = null; + + /** + * @var boolean Check other languages for URLSegment values (only applies to {@link SiteTree}). + * Turn this off to handle language setting yourself, e.g. through language-specific subdomains + * or URL path prefixes like "/en/mypage". + */ + private static $enforce_global_unique_urls = true; /** * Reset static configuration variables to their default values @@ -1743,11 +1750,14 @@ class Translatable extends DataExtension implements PermissionProvider { */ public function augmentValidURLSegment() { $reEnableFilter = false; - if(self::locale_filter_enabled()) { + if(!Config::inst()->get('Translatable', 'enforce_global_unique_urls')) { + self::enable_locale_filter(); + } elseif(self::locale_filter_enabled()) { self::disable_locale_filter(); $reEnableFilter = true; } - $IDFilter = ($this->owner->ID) ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null; + + $IDFilter = ($this->owner->ID) ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null; $parentFilter = null; if($this->owner->ParentID) { @@ -1759,9 +1769,9 @@ class Translatable extends DataExtension implements PermissionProvider { $existingPage = SiteTree::get() // disable get_one cache, as this otherwise may pick up results from when locale_filter was on ->where("\"URLSegment\" = '{$this->owner->URLSegment}' $IDFilter $parentFilter")->First(); - if($reEnableFilter) self::enable_locale_filter(); + // By returning TRUE or FALSE, we overrule the base SiteTree->validateURLSegment() logic return !$existingPage; } diff --git a/docs/en/index.md b/docs/en/index.md index 34c7466..6605c65 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -167,12 +167,17 @@ Creating a translation: 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 + +The `SiteTree.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 `[api:Versioned]` extension. +It ensures that all pages can be reached through their URL without any additional setup. +This behaviour can be turned off through the `Translatable.enforce_global_unique_urls` configuration setting, +in which case its up to you to ensure the language context can be derived from the URL +(e.g. through a subdomain or a language path prefix like `/en/mypage`). + +In either case, you'll need to take care that the appropriate "reading language" is set +before showing links to other pages on a website, for example through +a `locale` GET parameter (see `Translatable::choose_site_locale()`). Note: You can't get Children() for a parent page in a different language through set_reading_locale(). Get the translated parent first. @@ -188,9 +193,7 @@ through set_reading_locale(). Get the translated parent first. By default, the URLs generated for a page can only contain western characters ("ASCII"). You can configure this to accept the whole range of UTF8 characters as well. This is a SilverStripe core feature, rather than anything specific to this module. -Add the following to your `mysite/_config.php`: - - URLSegmentFilter::$default_allow_multibyte = true; +Refer to the `URLSegmentFilter.default_allow_multibyte` configuration setting. ### Translating custom properties diff --git a/tests/unit/TranslatableTest.php b/tests/unit/TranslatableTest.php index 9f765cf..f039d64 100755 --- a/tests/unit/TranslatableTest.php +++ b/tests/unit/TranslatableTest.php @@ -408,10 +408,17 @@ class TranslatableTest extends FunctionalTest { $translatedPage = $origPage->createTranslation('de_DE'); $this->assertEquals($translatedPage->URLSegment, 'testpage-de-de'); - $translatedPage->URLSegment = 'testpage'; + $translatedPage->URLSegment = 'testpage'; // de_DE clashes with en_US $translatedPage->write(); - $this->assertNotEquals($origPage->URLSegment, $translatedPage->URLSegment); + + Translatable::set_current_locale('de_DE'); + Config::inst()->update('Translatable', 'enforce_global_unique_urls', false); + $translatedPage->URLSegment = 'testpage'; // de_DE clashes with en_US + $translatedPage->write(); + $this->assertEquals('testpage', $translatedPage->URLSegment); + Config::inst()->update('Translatable', 'enforce_global_unique_urls', true); + Translatable::set_current_locale('en_US'); } function testUpdateCMSFieldsOnSiteTree() {