Hello,
I'm doing a one-page site in silverstripe and i have created some templates that will represent my different site parts.
I first tried to loop by using 'include' so :
<% if SlugItems %>
<% loop SlugItems %>
<% include $slug %>
<% end_loop %>
<% end_if %>
But from what i found on forums, it's not the way to do it and i got an error with loop tag missing...So i tried to create a function
public function IncludeTemplate($template) {
return $this->renderWith($template);
}
And
<% if SlugItems %>
<% loop SlugItems %>
<% IncludeTemplate($Slug) %>
<% end_loop %>
<% end_if %>
Big surprise...It's the same, cause i read that both include and renderWith do the same job. Well, i don't really know a good solution and i'd like to implement something more elaborate than including some template if my template name is like X, eg.
<% if $ClassName = 'SomeClass' %>
<% include SomeClass %>
<% else_if $ClassName = 'SomeOtherClass' %>
<% include SomeOtherClass %>
<% else %>
<% include DefaultClass %>
<% end_if %>
If you know a good solution, please write it here! That would make my day :D.
Thanks, Thomas
What it sounds like you are trying to do is similar to a module called Content Blocks.
In that module, they have an identical situation where they loop over blocks and insert the right template for that block.
The module's Page.ss
:
<% loop $ActiveBlocks %>$Me<% end_loop %>
$ActiveBlocks
refers to a function on a DataExtension by the same name.
This is all stuff that you are already familiar with. The part that you might not know so much about is the $Me
value in the template. It can be used to refer to the current object context the template is rendered with, in your case that would be a Slug
.
That is only part of the magic, the other part is a function on the Block
DataObject the called forTemplate
. This is called when using $Me
to work out how to render the DataObject.
In here, you can just perform a classic renderWith
call like this:
return $this->renderWith(array($this->Template, 'Slug'));
With this knowledge, you could achieve what you are after by having a Slug
DataObject looking something like this:
class Slug extends DataObject
{
static $db = array();
function getTemplate()
{
$template = 'yourTemplate';
//Do your template logic checks in here to work out what you want to display
return $template;
}
function forTemplate()
{
return $this->renderWith(array($this->Template, 'Slug'));
}
}
With your template looking something like this:
<% if $Slugs %>
<% loop $Slugs %>
$Me
<% end_loop %>
<% end_if %>
You can define a template file, say Slug.ss, where you put the HTML you want to loop over, and save it into themes/your-theme/templates/Includes.
Then you can just loop over it with this code:
<% if SlugItems %>
<% loop SlugItems %>
<% include Slug %>
<% end_loop %>
<% end_if %>
i did something similar in my onepage module
try something like that:
/**
* renders the current page using the ClassName_onepage template,
* e.g. Page_onepage
*
* @return HTMLText
*/
public function getOnePageContent(){
$templateName = SSViewer::get_templates_by_class($this->owner->Classname, '_onepage', 'SiteTree')
?: 'Page_onepage';
return $this->renderWith($templateName);
}
And in your template:
<% if SlugItems %>
<% loop SlugItems %>
$OnePageContent
<% end_loop %>
<% end_if %>
HTH,
wmk