Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Clarification of inheritance, please


7 Posts   1095 Views


4 December 2009 at 5:07am Community Member, 67 Posts

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 and, 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, it would default to using the parent template file, namely But it doesn't, it uses, skipping a generation. This is puzzling to me. It's not hugely problematic, because if I do create a file called, it does use it. It doesn't go well with the Don't Repeat Yourself philosophy, though, as it is fundamentally the same as

What have I misunderstood here? This is Silverstripe 2.3.4.


4 December 2009 at 9:35am Forum Moderator, 5511 Posts

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').


4 December 2009 at 9:48am (Last edited: 4 December 2009 9:53am), Forum Moderator, 921 Posts

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.


4 December 2009 at 10:00am Community Member, 67 Posts

Thanks, Willr and Sean. At least if it is a bug, I can presumably get around the consequences of it Willr's way.


5 December 2009 at 2:57am Community Member, 67 Posts

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 at the top level, and within the Layout directory, the standard and also

When I display a ChildPage record, it is automatically rendered with the Layout/ template. When I display a GrandChildPage record, though, it is not rendered with Layout/, despite it being a subclass of ChildPage, but is rendered instead with Layout/ 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, but ONLY with That is, it just renders the page fragment, not the whole page as rendered by with $Layout being rendered by, which is of course what I want. How do I force this to happen?


5 December 2009 at 4:33am Community Member, 283 Posts

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);
         $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.


5 December 2009 at 7:20am Community Member, 67 Posts

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.