NEW Translatable.enforce_global_unique_urls config setting

See https://github.com/silverstripe/silverstripe-cms/pull/216
and https://github.com/silverstripe/silverstripe-cms/pull/772
for context
This commit is contained in:
Ingo Schommer 2013-06-12 13:45:45 +02:00
parent b90e2294b5
commit b898134b11
3 changed files with 33 additions and 13 deletions

View File

@ -205,6 +205,13 @@ class Translatable extends DataExtension implements PermissionProvider {
*/ */
protected static $allowed_locales = null; 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 * Reset static configuration variables to their default values
*/ */
@ -1743,11 +1750,14 @@ class Translatable extends DataExtension implements PermissionProvider {
*/ */
public function augmentValidURLSegment() { public function augmentValidURLSegment() {
$reEnableFilter = false; $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(); self::disable_locale_filter();
$reEnableFilter = true; $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; $parentFilter = null;
if($this->owner->ParentID) { if($this->owner->ParentID) {
@ -1759,9 +1769,9 @@ class Translatable extends DataExtension implements PermissionProvider {
$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
->where("\"URLSegment\" = '{$this->owner->URLSegment}' $IDFilter $parentFilter")->First(); ->where("\"URLSegment\" = '{$this->owner->URLSegment}' $IDFilter $parentFilter")->First();
if($reEnableFilter) self::enable_locale_filter(); if($reEnableFilter) self::enable_locale_filter();
// By returning TRUE or FALSE, we overrule the base SiteTree->validateURLSegment() logic
return !$existingPage; return !$existingPage;
} }

View File

@ -167,12 +167,17 @@ Creating a translation:
If a child page translation is requested without the parent If a child page translation is requested without the parent
page already having a translation in this language, the extension page already having a translation in this language, the extension
will recursively create translations up the tree. 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. languages by auto-appending the language code at the end.
You'll need to ensure that the appropriate "reading language" is set It ensures that all pages can be reached through their URL without any additional setup.
before showing links to other pages on a website through $_GET['locale']. This behaviour can be turned off through the `Translatable.enforce_global_unique_urls` configuration setting,
Pages in different languages can have different publication states in which case its up to you to ensure the language context can be derived from the URL
through the `[api:Versioned]` extension. (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 Note: You can't get Children() for a parent page in a different language
through set_reading_locale(). Get the translated parent first. 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"). 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. 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. This is a SilverStripe core feature, rather than anything specific to this module.
Add the following to your `mysite/_config.php`: Refer to the `URLSegmentFilter.default_allow_multibyte` configuration setting.
URLSegmentFilter::$default_allow_multibyte = true;
### Translating custom properties ### Translating custom properties

View File

@ -408,10 +408,17 @@ class TranslatableTest extends FunctionalTest {
$translatedPage = $origPage->createTranslation('de_DE'); $translatedPage = $origPage->createTranslation('de_DE');
$this->assertEquals($translatedPage->URLSegment, 'testpage-de-de'); $this->assertEquals($translatedPage->URLSegment, 'testpage-de-de');
$translatedPage->URLSegment = 'testpage'; $translatedPage->URLSegment = 'testpage'; // de_DE clashes with en_US
$translatedPage->write(); $translatedPage->write();
$this->assertNotEquals($origPage->URLSegment, $translatedPage->URLSegment); $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() { function testUpdateCMSFieldsOnSiteTree() {