21490 Posts in 5783 Topics by 2622 members
|
Page:
1
|
Go to End | |
| Author | Topic: | 857 Views |
-
Clarification of inheritance, please

4 December 2009 at 5:07am
Something didn't work just now which I thought would, which suggests my understanding of the way inheritance works in Silverstripe is slightly flawed. I'm hoping someone can clarify things for me.
I have, as usual, a Page.php. I also have a ChildPage.php which extends that. In my themes directory, I have templates called Page.ss and ChildPage.ss, which behave exactly as they should. I also have a PHP class called StudentsPage, which extends ChildPage. My expectation was that unless I created a matching template file called StudentsPage.ss, it would default to using the parent template file, namely ChildPage.ss. But it doesn't, it uses Page.ss, skipping a generation. This is puzzling to me. It's not hugely problematic, because if I do create a file called StudentsPage.ss, it does use it. It doesn't go well with the Don't Repeat Yourself philosophy, though, as it is fundamentally the same as ChildPage.ss.
What have I misunderstood here? This is Silverstripe 2.3.4.
-
Re: Clarification of inheritance, please

4 December 2009 at 9:35am
I believe this is just a limitation with the SSViewer. AFAIK How it works is it looks for a template with the same classname, if it can't find one then it defaults to page. It doesn't take any inheritance / class structure into account. You could customize the rendering of StudentPage by supplying a custom renderWith('ChildPage').
-
Re: Clarification of inheritance, please

4 December 2009 at 9:48am Last edited: 4 December 2009 9:53am
SilverStripe should have gone through the template stack, going up until it finds a template to render with. Perhaps this is a bug, as I'd expect it to work the way you want it.
-
Re: Clarification of inheritance, please

4 December 2009 at 10:00am
Thanks, Willr and Sean. At least if it is a bug, I can presumably get around the consequences of it Willr's way.
-
Re: Clarification of inheritance, please

5 December 2009 at 2:57am
I just created a little SS website purely to test this out, and I can confirm that in the case of a class hierarchy more than 2 levels deep, SilverStripe doesn't go up the template stack until it finds a template to render with, it goes straight to the Page template. At least, as structured in my little site it does. Just to make this clearer:
I have 3 classes - the standard Page.php; ChildPage.php which extends Page.php; and GrandChildPage.php which extends ChildPage.php.
In my templates, I have the standard Page.ss at the top level, and within the Layout directory, the standard Page.ss and also ChildPage.ss.
When I display a ChildPage record, it is automatically rendered with the Layout/ChildPage.ss template. When I display a GrandChildPage record, though, it is not rendered with Layout/ChildPage.ss, despite it being a subclass of ChildPage, but is rendered instead with Layout/Page.ss. This definitely doesn't strike me as what it should do.
I said I could get round the consequences of this by using renderWith, but I'm evidently not using it right. In my GrandChildPage_Controller class, I tried adding this:
function Index(){
return $this->renderWith("ChildPage");
}It does indeed render it with ChildPage.ss, but ONLY with ChildPage.ss. That is, it just renders the page fragment ChildPage.ss, not the whole page as rendered by Page.ss with $Layout being rendered by ChildPage.ss, which is of course what I want. How do I force this to happen?
-
Re: Clarification of inheritance, please

5 December 2009 at 4:33am
renderWith() only invokes the specific template you sent to it, and doesn't traverse up the regular Layout paths. Currently in 2.3 you are limited to the Page/Layout method of 2 levels. Templates don't inherit along side subclasses as they are selected by where you are generating content for, not by a hierarchical "Who's your daddy".
You can probably force it to render with your templates manually by mimicking the way SSViewer processes templates in your controller.
public function index() {
foreach(array('GrandChildPage','ChildPage') as $template) {
$subtemplateViewer = new SSViewer($template);
$this->customise(array(
$template => $subtemplateViewer->process($this)
));
}
return $this->renderWith('Page');Check out SSViewer.php, Line 303 for more meat. I'm not 100% sure this will work but if you need a custom rendering solution beyond the Layout method you're going to have to do something like this.
Perhaps you could rethink your layout to use the 2 level system or create a new template with everything from your Page and ChildPage (html to /html) and use renderWith() on that. Its dirty but it works.
-
Re: Clarification of inheritance, please

5 December 2009 at 7:20am
Thanks, that's very helpful and it does clarify things. It's not a huge problem and I can certainly work around it. I was just wanting to be clear about how it should work.
| 857 Views | ||
|
Page:
1
|
Go to Top |




