Reputation: 255
SilverStripe 3.1.x How to Render with a specific template from an Extension?
In SilverStripe 3.1.x, How can I make a Page render with a specific template from a Module Extension? I'm working on a module that allows an administrator to change the display behaviour of a page at specific timeframes. Making the page redirect works fine, but when it comes to rendering with a specific template, it seems to get ignored.
Here's an excerpt of the key parts of my code:
mymodule/_config/mymodule.yml
---
Name: mymodule
After:
- 'framework/*'
- 'cms/*'
---
Page_Controller:
extensions:
- MyPage_ControllerExtension
mymodule/code/MyPage_ControllerExtension.php
class MyPage_ControllerExtension extends Extension {
public function onAfterInit() {
//Render with MyTestTemplate.ss as a test
return $this->owner->renderWith(array('MyTestTemplate', 'Page')); //Don't work
//try redirecting
//return $this->owner->redirect('http://google.com'); //Works fine
}
}
mysite/code/Page.php
class Page_Controller extends ContentController {
private static $allowed_actions = array ();
public function init() {
parent::init();
}
}
themes/simple/templates/Layout/MyTestTemplate.ss
<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
<article>
<h1>MY TEST TEMPLATE</h1>
<div class="content">MY TEST CONTENT</div>
</article>
</div>
After flushing the template cache, SilverStripe does not render Page.ss with MyTestTemplate. How do I achieve that from the MyPage_ControllerExtension above?
When I debug by adding the parameter ?showtemplate=1 to the URL, I can see that SilverStripe does indeed get the content for MyTestTemplate, but in the end, it ignores it and the Layout/Page.ss template gets used instead.
Upvotes: 0
Views: 2029
Reputation: 255
So, the final solution, from @Martimiz, which works whether or not an action is called is:
In the Page_Controller class in mysite/code/Page.php, add the following property as follows:
class Page_Controller extends ContentController {
public $templates;
⋮
}
In mymodule/code/MyPage_ControllerExtension.php, add:
class MyPage_ControllerExtension extends Extension {
public function onAfterInit() {
$action = $this->owner->request->param('Action');
if(!$action) $action = 'index';
$this->owner->templates[$action] = array('MyTestTemplate', 'Page');
}
}
Upvotes: 0
Reputation: 28
This would work for actions and index functions when default rendering is used (by returning array() or $this)
public function onAfterInit() {
$this->owner->templates['index'] = array('MyTestTemplate', 'Page');
}
You could also use $this->owner->templates['currentaction'] if you want
But you'd have to add the following property to your Page_Controller class, because although it is checked from within the Controller class, it doesn't seem to be defined anywhere in the class chain (?):
public $templates;
Upvotes: 1
Reputation: 28
You could use the index() function in your (Data)Extension to return the rendered data:
public function index() {
return $this->owner->renderWith(array('MyTestTemplate', 'Page'));
}
Note: that would fail though, if the Page you're extending already has an index() function defined.
Upvotes: 0