John Davidson

php - silverstripe: use another "root" - template instead of "Page.ss"

0 comments
Message:


Is it possible to render another "root" template instead of the Page.ss file for some specific pages / controllers? There are already some pages using the Page.ss template, but now there will be a new "Intranet" section on the website where the pages should have another "root" template: IntranetPage.ss.


Page.ss should stay as is and should not be touched at all.


I mainly want different "root" templates because both templates load different JS and CSS files. Also the "container" HTML is quite different.


I was able to create a custom controller which does manually what I need. Something like this:


class IntranetPageController extends PageController
{
public function index()
{
return $this->customise([
'Layout' => $this->renderWith(['Intranet/Layout/IntranetPageLayout'])
])->renderWith(['Intranet/IntranetPage']);
}
}

The code is inspired from here: https://docs.silverstripe.org/en/4/developer_guides/templates/rendering_templates/


IntranetPage.ss is used now as the "root" template. IntranetPageLayout.ss is displayed for the $Layout placeholder.


That seems to work, however I have many pages which have to be based on IntranetPage.ss. It feels strange to write for every new Controller the very same index function (with a small adjustment to load another LayoutPage).


I am sure, Silverstripe has some convention to do that automatically :)


What I need is very close to having a individual theme per page, but I am not sure if that is possible...



My Answer:
One way to achieve this in Silverstripe is by using the "Layout" field in the Page class. You can set the default layout for all pages to Page.ss, and then override it for specific pages by setting the Layout field to IntranetPage.ss.

Here's how you can do it:

1. Create a new field in your Page class to store the layout template name:

php
private static $db = [
'Layout' => 'Varchar(255)'
];


2. Set the default layout to Page.ss in your Page class:

php
private static $defaults = [
'Layout' => 'Page'
];


3. Override the layout for specific pages by setting the Layout field in the CMS:

yaml
SilverStripe\CMS\Model\SiteTree:
extensions:
- 'PageLayoutExtension'


4. Create a PageLayoutExtension class to handle the logic for setting the layout template:

php
class PageLayoutExtension extends DataExtension
{
public function updateTemplateFile($template)
{
if ($this->owner->Layout) {
return $this->owner->Layout;
}

return $template;
}
}


5. Finally, update your templates to use the Layout field:

html
<% include $Layout %>


Now, when you create a new page in the CMS, you can set the Layout field to IntranetPage.ss to use that template instead of Page.ss. This way, you don't have to manually override the index function in each controller.

Rate this post

3 of 5 based on 2715 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us