mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02: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
|
||||
// nested URL.
|
||||
if($action && SiteTree::nested_urls() && !$this->hasAction($action)) {
|
||||
// See ModelAdController->getNestedController() for similar logic
|
||||
Translatable::disable_locale_filter();
|
||||
|
||||
$child = DataObject::get_one('SiteTree', sprintf (
|
||||
"\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action)
|
||||
));
|
||||
|
||||
Translatable::enable_locale_filter();
|
||||
}
|
||||
|
||||
@ -157,6 +156,18 @@ class ContentController extends Controller {
|
||||
|
||||
$response = ModelAsController::controller_for($child)->handleRequest($request);
|
||||
} 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());
|
||||
$response = parent::handleRequest($request);
|
||||
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.');
|
||||
}
|
||||
|
||||
// Find page by link, regardless of current locale settings
|
||||
Translatable::disable_locale_filter();
|
||||
|
||||
$sitetree = DataObject::get_one('SiteTree', sprintf (
|
||||
'"URLSegment" = \'%s\' %s', Convert::raw2sql($URLSegment), (SiteTree::nested_urls() ? 'AND "ParentID" = 0' : null)
|
||||
));
|
||||
|
||||
$sitetree = DataObject::get_one(
|
||||
'SiteTree',
|
||||
sprintf(
|
||||
'"URLSegment" = \'%s\' %s',
|
||||
Convert::raw2sql($URLSegment),
|
||||
(SiteTree::nested_urls() ? 'AND "ParentID" = 0' : null)
|
||||
)
|
||||
);
|
||||
Translatable::enable_locale_filter();
|
||||
|
||||
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(isset($_REQUEST['debug'])) {
|
||||
|
@ -728,9 +728,12 @@ class Translatable extends DataObjectDecorator implements PermissionProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: The bulk of logic is in ModelAsController->getNestedController()
|
||||
* and ContentController->handleRequest()
|
||||
*/
|
||||
function contentcontrollerInit($controller) {
|
||||
Translatable::choose_site_locale();
|
||||
$controller->Locale = Translatable::get_current_locale();
|
||||
$controller->Locale = Translatable::choose_site_locale();
|
||||
}
|
||||
|
||||
function modelascontrollerInit($controller) {
|
||||
|
@ -22,6 +22,8 @@ class TranslatableTest extends FunctionalTest {
|
||||
|
||||
private $origLocale;
|
||||
|
||||
protected $autoFollowRedirection = false;
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
@ -40,6 +42,25 @@ class TranslatableTest extends FunctionalTest {
|
||||
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() {
|
||||
// first in french
|
||||
$frPage = new SiteTree();
|
||||
|
Loading…
Reference in New Issue
Block a user