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, Ed, biapar, Willr, Ingo, swaiba

Clarification of inheritance, please

Go to End

7 Posts   1453 Views


Community Member, 67 Posts

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


Forum Moderator, 5523 Posts

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


Forum Moderator, 922 Posts

4 December 2009 at 9:48am

Edited: 04/12/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.


Community Member, 67 Posts

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.


Community Member, 67 Posts

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 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?


Community Member, 283 Posts

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


Community Member, 67 Posts

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.