diff --git a/code/Controllers/ContentController.php b/code/Controllers/ContentController.php index d1ff25b3..32b09bc4 100644 --- a/code/Controllers/ContentController.php +++ b/code/Controllers/ContentController.php @@ -440,16 +440,24 @@ HTML; $action = '_' . $action; } - $templates = array_merge( - // Find templates by dataRecord - SSViewer::get_templates_by_class(get_class($this->dataRecord), $action, "SilverStripe\\CMS\\Model\\SiteTree"), - // Next, we need to add templates for all controllers - SSViewer::get_templates_by_class(static::class, $action, "SilverStripe\\Control\\Controller"), - // Fail-over to the same for the "index" action - SSViewer::get_templates_by_class(get_class($this->dataRecord), "", "SilverStripe\\CMS\\Model\\SiteTree"), - SSViewer::get_templates_by_class(static::class, "", "SilverStripe\\Control\\Controller") - ); + $templatesFound = []; + // Find templates for the record + action together - e.g. Page_action.ss + if ($this->dataRecord instanceof SiteTree) { + $templatesFound[] = $this->dataRecord->getViewerTemplates($action); + } + // Find templates for the controller + action together - e.g. PageController_action.ss + $templatesFound[] = SSViewer::get_templates_by_class(static::class, $action, Controller::class); + + // Find templates for the record without an action - e.g. Page.ss + if ($this->dataRecord instanceof SiteTree) { + $templatesFound[] = $this->dataRecord->getViewerTemplates(); + } + + // Find the templates for the controller without an action - e.g. PageController.ss + $templatesFound[] = SSViewer::get_templates_by_class(static::class, "", Controller::class); + + $templates = array_merge(...$templatesFound); return SSViewer::create($templates); } diff --git a/code/Model/VirtualPage.php b/code/Model/VirtualPage.php index 4757eadf..3d96ea99 100644 --- a/code/Model/VirtualPage.php +++ b/code/Model/VirtualPage.php @@ -2,6 +2,7 @@ namespace SilverStripe\CMS\Model; +use Page; use SilverStripe\Core\Convert; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\LiteralField; @@ -9,9 +10,9 @@ use SilverStripe\Forms\ReadonlyTransformation; use SilverStripe\Forms\TreeDropdownField; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\ValidationResult; -use SilverStripe\Versioned\Versioned; use SilverStripe\Security\Member; -use Page; +use SilverStripe\Versioned\Versioned; +use SilverStripe\View\SSViewer; /** * Virtual Page creates an instance of a page, with the same fields that the original page had, but readonly. @@ -277,8 +278,8 @@ class VirtualPage extends Page public function onBeforeWrite() { - parent::onBeforeWrite(); $this->refreshFromCopied(); + parent::onBeforeWrite(); } /** @@ -368,6 +369,22 @@ class VirtualPage extends Page return parent::CMSTreeClasses() . ' VirtualPage-' . $this->CopyContentFrom()->ClassName; } + /** + * Use the target page's class name for fetching templates - as we need to take on its appearance + * + * @param string $suffix + * @return array + */ + public function getViewerTemplates($suffix = '') + { + $copy = $this->CopyContentFrom(); + if ($copy && $copy->exists()) { + return $copy->getViewerTemplates($suffix); + } + + return parent::getViewerTemplates($suffix); + } + /** * Allow attributes on the master page to pass * through to the virtual page diff --git a/tests/php/Model/VirtualPageTest.php b/tests/php/Model/VirtualPageTest.php index 2fccb44a..f521816d 100644 --- a/tests/php/Model/VirtualPageTest.php +++ b/tests/php/Model/VirtualPageTest.php @@ -632,6 +632,18 @@ class VirtualPageTest extends FunctionalTest $this->assertEquals(200, $response->getStatusCode()); $this->assertContains('TestContent', $response->getBody()); $this->assertNotContains('NotThisContent', $response->getBody()); + + // VirtualPageTest_ClassB doesn't have an associated controller for + // ModelAsController::controller_for() to find + $page = new VirtualPageTest_ClassB(); + $page->Title = 'Test Page B'; + $page->write(); + $vp = new VirtualPage(); + $vp->CopyContentFromID = $page->ID; + $vp->write(); + $response = $this->get($vp->Link()); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertContains('Test Page B', $response->getBody()); }); } diff --git a/tests/php/Model/themes/virtualpagetest/templates/SilverStripe/CMS/Tests/Model/VirtualPageTest_ClassB.ss b/tests/php/Model/themes/virtualpagetest/templates/SilverStripe/CMS/Tests/Model/VirtualPageTest_ClassB.ss new file mode 100644 index 00000000..ba1bcd53 --- /dev/null +++ b/tests/php/Model/themes/virtualpagetest/templates/SilverStripe/CMS/Tests/Model/VirtualPageTest_ClassB.ss @@ -0,0 +1 @@ +
$Title