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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Template Questions /

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

Nested Templates


Go to End


7 Posts   2265 Views

Avatar
matthewjumps

Community Member, 21 Posts

4 August 2010 at 8:16pm

Im trying to make a single HTML page for my site that is going to be consumed by a Flash file (for a full flash website).

I want this page to contain the HTML for ALL pages on my site, all output in the one place.

The structure will basically be the usual head and footer stuff, along with a nav, but then in the main content area, for each page I want to have a simple HTML snippet <div class="page" id="uniqueURL"></div> with the content for that particular page in it.

This would be a piece of cake if there were only top level pages. But...

I want this to work with ANY level of nested pages. Each <div class="page"> can contain another <div class="subs"></div>, and in a page's 'subs' div, there will be more <div class="page"> objects, any of which could ALSO contain subs... and so on.

Is there any way to recursively call the same 'Page' template for each level of child pages?

Avatar
matthewjumps

Community Member, 21 Posts

16 August 2010 at 5:30pm

bumpity?

Avatar
bummzack

Community Member, 904 Posts

16 August 2010 at 6:32pm

Edited: 16/08/2010 6:35pm

Yep, it's certainly possible. Here's how I did this for exporting my whole Site-Tree to XML (also for reading into flash):

1) Go to your template folder and create a new folder called "export" or similar. This is purely for organizing your templates... if you plan to output your site as regular HTML-site for people without Flash, then this is going to help you keeping your templates structured.

2) Think about a good prefix for your templates. We don't want to mess with the default SilverStripe templating mechanisms, so we're going to prefix all our templates. In this example, I chose Export as the prefix.

3) On your Page class, create a function like this:

/**
 * Render the page for export
 * @return string
 */
public function ExportContent(){
	$viewer = new SSViewer(array('Export' . $this->ClassName, 'ExportPage'));
	return $viewer->process($this);
}

As you can see, I'm using the 'Export' prefix here to render the page with a custom template. This function works for all subclasses of page as well. First the export will always use Export + <ClassName>, if that template doesn't exist, it will fall back to ExportPage

4) Obviously we need a matching template now.. create a new File called ExportPage.ss in the templates/export folder. This file should only contain the stuff needed to export the data of a page. Do not put HTML Headers and stuff there. Here's an example of such a file:

<div>
	<h1>$Title</h1>
	$Content
	<% if Children %>
	<div class="children">
		<% control Children %>
		$ExportContent
		<% end_control %>
	</div>
	<% end_if %>
</div>

The interesting bit here is the call to $ExportContent, which is basically going to call the ExportContent function of all children, thus rendering their content out as well. Of course you can fully customize the template.. just don't forget to export the contents of the children as well.

5) Now we're basically set. All we need to add is an entry point to our export. We do this, by creating a function on the Page_Controller class. The method looks like this:

public function export(){
	return array();
}

Now you just need a template for this method. In your templates folder, create a file named Page_export.ss. This file can then contain all the HTML Headers and footers and should contain something like this:

<!-- HTML Headers and stuff here -->
<% control Menu(1) %>
$ExportContent
<% end_control %>
<!-- HTML Footer... -->

This gets the level 1 SiteTree objects and exports their content...

6) You're set and ready to go. Just open yoursite.com/somepage/export in your browser and it will export the whole SiteTree as one HTML file (maybe you'll have to add ?flush=1 to the URL the first time you do the export).

Hope that helps.

Update: If you need different export templates for different types of pages, this is not a problem at all. E.g. you have a page class named TestimonialPage and need it to export differently than regular pages, then just create a template named ExportTestimonialPage.ss in templates/export and fill it with the desired template code...

Avatar
matthewjumps

Community Member, 21 Posts

16 August 2010 at 6:59pm

Wow thank you banal for the detailed response, that is extremely helpful :)

I'll try my hand at implementing it, glad to see its relatively straightforward.

Thanks again :D

Avatar
matthewjumps

Community Member, 21 Posts

25 August 2010 at 3:33pm

OK that is working great, but one thing I cant figure out is how to allow you to just go to yoursite.com/export instead of having to view yoursite.com/somepage/export

Is that possible?

Avatar
matthewjumps

Community Member, 21 Posts

28 August 2010 at 11:21am

re-bumpity?

Avatar
matthewjumps

Community Member, 21 Posts

29 August 2010 at 2:41pm

Well I worked it out. Silverstripe is quite cool!

I created an ExportPage page type and controller, then in the ExportPage.ss template used the code you said to put in Page_export.ss

I left the ExportContent() function on the Page class, and then added a folder in the templates folder to correspond with ExportContent. I reordered the export template names to be "PageExport.ss" or "ArticlePageExport.ss" instead of "ExportPage.ss" - and then voila, create a new top level page in the CMS with the url /export and it works!

Thanks for all the help :)