mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT Redirecting to translated page when original is requested with a 'locale' GET parameter (e.g. 'about-us/?locale=de_DE' will redirect to 'ueber-uns' with a 301 HTTP response). Implemented in ContentController->handleRequest(). (see #5001) (from r100937)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@111545 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
37bc333882
commit
94d98b18ac
@ -142,12 +142,11 @@ class ContentController extends Controller {
|
|||||||
// control to a child controller. This allows for the creation of chains of controllers which correspond to a
|
// control to a child controller. This allows for the creation of chains of controllers which correspond to a
|
||||||
// nested URL.
|
// nested URL.
|
||||||
if($action && SiteTree::nested_urls() && !$this->hasAction($action)) {
|
if($action && SiteTree::nested_urls() && !$this->hasAction($action)) {
|
||||||
|
// See ModelAdController->getNestedController() for similar logic
|
||||||
Translatable::disable_locale_filter();
|
Translatable::disable_locale_filter();
|
||||||
|
|
||||||
$child = DataObject::get_one('SiteTree', sprintf (
|
$child = DataObject::get_one('SiteTree', sprintf (
|
||||||
"\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action)
|
"\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action)
|
||||||
));
|
));
|
||||||
|
|
||||||
Translatable::enable_locale_filter();
|
Translatable::enable_locale_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +156,18 @@ class ContentController extends Controller {
|
|||||||
|
|
||||||
$response = ModelAsController::controller_for($child)->handleRequest($request);
|
$response = ModelAsController::controller_for($child)->handleRequest($request);
|
||||||
} else {
|
} else {
|
||||||
|
// If a specific locale is requested, and it doesn't match the page found by URLSegment,
|
||||||
|
// look for a translation and redirect (see #5001). Only happens on the last child in
|
||||||
|
// a potentially nested URL chain.
|
||||||
|
if($request->getVar('locale') && $this->dataRecord && $this->dataRecord->Locale != $request->getVar('locale')) {
|
||||||
|
$translation = $this->dataRecord->getTranslation($request->getVar('locale'));
|
||||||
|
if($translation) {
|
||||||
|
$response = new SS_HTTPResponse();
|
||||||
|
$response->redirect($translation->Link(), 301);
|
||||||
|
throw new SS_HTTPResponse_Exception($response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Director::set_current_page($this->data());
|
Director::set_current_page($this->data());
|
||||||
$response = parent::handleRequest($request);
|
$response = parent::handleRequest($request);
|
||||||
Director::set_current_page(null);
|
Director::set_current_page(null);
|
||||||
|
@ -87,12 +87,16 @@ class ModelAsController extends Controller implements NestedController {
|
|||||||
throw new Exception('ModelAsController->getNestedController(): was not passed a URLSegment value.');
|
throw new Exception('ModelAsController->getNestedController(): was not passed a URLSegment value.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find page by link, regardless of current locale settings
|
||||||
Translatable::disable_locale_filter();
|
Translatable::disable_locale_filter();
|
||||||
|
$sitetree = DataObject::get_one(
|
||||||
$sitetree = DataObject::get_one('SiteTree', sprintf (
|
'SiteTree',
|
||||||
'"URLSegment" = \'%s\' %s', Convert::raw2sql($URLSegment), (SiteTree::nested_urls() ? 'AND "ParentID" = 0' : null)
|
sprintf(
|
||||||
));
|
'"URLSegment" = \'%s\' %s',
|
||||||
|
Convert::raw2sql($URLSegment),
|
||||||
|
(SiteTree::nested_urls() ? 'AND "ParentID" = 0' : null)
|
||||||
|
)
|
||||||
|
);
|
||||||
Translatable::enable_locale_filter();
|
Translatable::enable_locale_filter();
|
||||||
|
|
||||||
if(!$sitetree) {
|
if(!$sitetree) {
|
||||||
@ -113,6 +117,7 @@ class ModelAsController extends Controller implements NestedController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enforce current locale setting to the loaded SiteTree object
|
||||||
if($sitetree->Locale) Translatable::set_current_locale($sitetree->Locale);
|
if($sitetree->Locale) Translatable::set_current_locale($sitetree->Locale);
|
||||||
|
|
||||||
if(isset($_REQUEST['debug'])) {
|
if(isset($_REQUEST['debug'])) {
|
||||||
|
@ -245,7 +245,7 @@ class Translatable extends DataObjectDecorator implements PermissionProvider {
|
|||||||
} else {
|
} else {
|
||||||
self::set_current_locale(self::default_locale());
|
self::set_current_locale(self::default_locale());
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$current_locale;
|
return self::$current_locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,9 +728,12 @@ class Translatable extends DataObjectDecorator implements PermissionProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: The bulk of logic is in ModelAsController->getNestedController()
|
||||||
|
* and ContentController->handleRequest()
|
||||||
|
*/
|
||||||
function contentcontrollerInit($controller) {
|
function contentcontrollerInit($controller) {
|
||||||
Translatable::choose_site_locale();
|
$controller->Locale = Translatable::choose_site_locale();
|
||||||
$controller->Locale = Translatable::get_current_locale();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function modelascontrollerInit($controller) {
|
function modelascontrollerInit($controller) {
|
||||||
|
@ -21,6 +21,8 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private $origLocale;
|
private $origLocale;
|
||||||
|
|
||||||
|
protected $autoFollowRedirection = false;
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -39,6 +41,25 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testLocaleGetParamRedirectsToTranslation() {
|
||||||
|
$origPage = $this->objFromFixture('Page', 'testpage_en');
|
||||||
|
$origPage->publish('Stage', 'Live');
|
||||||
|
$translatedPage = $origPage->createTranslation('de_DE');
|
||||||
|
$translatedPage->URLSegment = 'ueber-uns';
|
||||||
|
$translatedPage->write();
|
||||||
|
$translatedPage->publish('Stage', 'Live');
|
||||||
|
|
||||||
|
$response = $this->get($origPage->URLSegment);
|
||||||
|
$this->assertEquals(200, $response->getStatusCode(), 'Page request without Locale GET param doesnt redirect');
|
||||||
|
|
||||||
|
$response = $this->get(Controller::join_links($origPage->URLSegment, '?locale=de_DE'));
|
||||||
|
$this->assertEquals(301, $response->getStatusCode(), 'Locale GET param causes redirect if it exists');
|
||||||
|
$this->assertContains($translatedPage->URLSegment, $response->getHeader('Location'));
|
||||||
|
|
||||||
|
$response = $this->get(Controller::join_links($origPage->URLSegment, '?locale=xx_XX'));
|
||||||
|
$this->assertEquals(200, $response->getStatusCode(), 'Locale GET param without existing translation shows original page');
|
||||||
|
}
|
||||||
|
|
||||||
function testTranslationGroups() {
|
function testTranslationGroups() {
|
||||||
// first in french
|
// first in french
|
||||||
@ -174,7 +195,7 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
$origPage = $this->objFromFixture('Page', 'testpage_en');
|
$origPage = $this->objFromFixture('Page', 'testpage_en');
|
||||||
$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';
|
||||||
$translatedPage->write();
|
$translatedPage->write();
|
||||||
|
|
||||||
@ -692,7 +713,7 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
$enPage = new $type();
|
$enPage = new $type();
|
||||||
$enPage->Locale = 'en_US';
|
$enPage->Locale = 'en_US';
|
||||||
$enPage->write();
|
$enPage->write();
|
||||||
|
|
||||||
$dePage = $enPage->createTranslation('de_DE');
|
$dePage = $enPage->createTranslation('de_DE');
|
||||||
$dePage->write();
|
$dePage->write();
|
||||||
$this->assertEquals('de_DE', $dePage->Locale, "Page type $type retains Locale property");
|
$this->assertEquals('de_DE', $dePage->Locale, "Page type $type retains Locale property");
|
||||||
@ -875,7 +896,7 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
SiteTree::get_by_link($grandchildTranslation->Link())->ID,
|
SiteTree::get_by_link($grandchildTranslation->Link())->ID,
|
||||||
'Grandchild pages can be found.'
|
'Grandchild pages can be found.'
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO Re-enable test after clarifying with ajshort (see r88503).
|
// TODO Re-enable test after clarifying with ajshort (see r88503).
|
||||||
// Its unclear if this is valid behaviour, and/or necessary for translated nested URLs
|
// Its unclear if this is valid behaviour, and/or necessary for translated nested URLs
|
||||||
// to work properly
|
// to work properly
|
||||||
|
Loading…
x
Reference in New Issue
Block a user