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.

Template Questions /

Can someone please help me with this? Including a page on a page... or other options..


Reply


3 Posts   1201 Views

Avatar
MikeOne

Community Member, 40 Posts

22 October 2009 at 10:03am

Edited: 22/10/2009 10:36pm

Hi SS specialists,

I'm pretty new at Silverstripe and still trying to get my head around the correct (MVC) implementations of things. I was hoping you guys could help me on my way with the following thing I'm trying to implement.

I need to be able to have a tabbed block on a page (I will be using the jQuery UI Tabs) so for this I need to implement 2 structures on a page like:

structure 1:

<ul>
<li><a href="#fragment-1"><span>One</span></a></li>
<li><a href="#fragment-2"><span>Two</span></a></li>
<li><a href="#fragment-3"><span>Three</span></a></li>
</ul>

structure 2:

<div id="fragment-1">
<p>First tab is active by default:</p>
<pre><code>$('#example').tabs();</code></pre>
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>

Basically - structure 1 controls the tabs and structure 2 contains the content of the tabs. For an example see http://jqueryfordesigners.com/demo/tabs.html

This tab block will have to be included on a 'normal' content page. A different Tab block (so different tabs and content) must be included per page.

I was thinking that the easiest way for the content editors to control the content of these tabs would be to be able to add a 'TabContainer' (pagetype) as a child of the page it needs to go on and then add TabContent (pagetypes) to the TabContainer PageType. So in the CMS it would look something like:

Home
- TabsContainer (so child of Home)
-- TabContent 1
-- TabContent 2
Contact Us
About Us
- TabsContainer (so child of About us and different Tab content as Home)
-- TabContent 1
-- TabContent 2
Another Page

Obviousy, the TabContainer and TabContent page types should not show up in the menu so this can be switched off in static_defaults. Here i can also force that a TabContainer can only contain TabContent items. All no problems setting this up so far..

Basically -the content of the Tab should be a normal page that the editors can edit in the CMS, It can contain any HTML element, lists, images, even SWF's so this is the reason why I think the setup as explained should be the easiest for them.

Now... How am I going to do this? Basically - I need to be able to add a Page (TabsContainer including the children TabContents) to it's parent so basically 'Page.ss'.

I have had a look at the NewsArticle example in the tutorial - but this doesn't do what it needs to do as it includes DataObject items, not pages (so also no 'View' in the MVC model) - and in addition to that - the NewArticle example has visual pages (so included in the menu). It also is no good as the News Article are not children of a page but global articles.

I guess I need to do the following after setting up the explained structure as above:

- in the page_controller for mysite/code/Page.php I get a reference to the tabsContainer belonging to the current page so something like:

class Page_Controller extends ContentController {
   
   function getTabContainer(){
      $tabContainer = DataObject::get("TabContainer", "ParentID = $this->ID");
      
   }

}

Then in Page.ss, I could maybe (?) use something like:

<% control getTabContainer %>
$Title (should be the Title of the tabContainer as set in the CMS)
<% control Children %> (Should control the children of the TabContainer so the TabContent items...right?)
$content (so the content of the Tab
<% end_control %>
<% end_control %>

However - the above doesn't work.. One reason for this is because the ShowInMenu is set to null and there are no children available. Also - I'm getting a DataObject, which (I guess) means that there is no view (for example a /templates/Layout/TabContent.ss) associated with it..

What is the right way to get this done? I really like to have the CMS structure as described above (so the page that needs a tab container has a child TabContainer with TabContent children). How do I get the views of those TabContainer/Tabcontent(s) inside of any page that inherits from 'Page.ss' ?

Any pointers please? I really think this would be helpful to a lot of people who would like to implement something like this as the output might be a tabcontainer in my particular case - but the principle could be used for a lot of content related features.

Help please ;-)

Best regards,
Mike.

Avatar
zenmonkey

Community Member, 532 Posts

25 October 2009 at 4:48am

First off the standard Children control will only show Children that have a show in menus turned on. The AllChildren control will show all children regardless off "show in menu' state. You should be able to nest that control as much as you want. You'll need to run the control loop twice, once to generate your list, and once to generate your divs. You can use the $URLSegment to create unique IDs but you'll have to disable rewriteHashLinks http://doc.silverstripe.org/doku.php?id=templates&s=rewritehashlinks#fragment_link_rewriting

//generate your list
<% control getTabContainer %>

<ul>
<% control AllChildren %>

<li><a href="#$URLSegment"></span>$Title</span></a></li>

<% end_control %>
</ul>

<% end_control %>

//Generate your content
<% control getTabContainer %>
<% control AllChildren>

<div id="$URLSegment'>
$Content
</div>

<% end_control %>
<% end_control %>

Personally I prefer using the Semantic Tab Plugin(http://christianyates.com/blog/semantic-tabs/semantic-tabs-jquery), since you can just generate one control loop to generate your panels and it uses a Heading Tag in each panel to generate the Tab Titles. In Your Case it would be:

<% control getTabContainer %>
$Title
<div id="SemanticTabs'>
<% control AllChildren %>
<div class="panel">
<h3>$Title</h3>
$Content
</div>
<% end_control %>
</div>
<% end_control %>

Avatar
MikeOne

Community Member, 40 Posts

26 October 2009 at 12:36am

Excellent - thanks!

I have got it to work very nicely now. Thanks also for the tip about Semantic Tabs - it saves me from having to so 2 control loops so even cleaner now ;-)

I noticed that I was thinking way to complicated in finding a solution for this - the more I work with SS - the more I find out how easy it actually is once you get your head around it! Love it!

Cheers,
Mike.