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.

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

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

<% control Page() %> feature not working?


Go to End


13 Posts   5846 Views

Avatar
Mohammed

Community Member, 25 Posts

21 December 2009 at 12:49am

Edited: 21/12/2009 12:55am

I'm trying to design a footer-sitemap area to show up on the bottom of all my pages. Here is a quick layout:
Home(themes/template/Page.ss)
Articles(themes/template/layout/ArticleHolder)
->Article 1(themes/template/layout/ArticlePage)
->article 2(themes/template/layout/ArticlePage)
->article 3(themes/template/layout/ArticlePage)
Services(themes/template/layout/ServicesHolder)
->Service 1(themes/template/layout/ServicesPage)
->Service 2(themes/template/layout/ServicesPage)

In my themes/template/Page.ss file I'm calling on

<% control Page(ArticleHolder) %>$Title<% end_control %>
to start off by inserting the ArticleHolder page title (which is also the subject of the list); Returning the word "Articles". Yet doing this, nothing comes up.

Exact code in the themes/template/Page.ss template file:

<li><% control Page(ArticlePage) %>$Title<% end_control %></li>

Exact code in the ArticleHolder.php:

<?php
/**
 * Defines the ArticleHolder page type
 */
class ArticleHolder extends Page {
   static $db = array(
   );
   static $has_one = array(
   );
   static $allowed_children = array('ArticlePage');
   static $icon = "themes/tutorial/images/treeicons/news";
}
 
class ArticleHolder_Controller extends Page_Controller {
	function rss() {
    	$rss = new RSSFeed($this->Children(), $this->Link(), "The coolest news around");
    	$rss->outputToBrowser();
	}
	function init() {
   		RSSFeed::linkToFeed($this->Link() . "rss");	
   		parent::init();
	}
}
 
?>

I read that this type of control is done with the DataObjectControler, hence why I posted in this forum. Any suggestions on how to go about making this work?

Avatar
dhensby

Community Member, 253 Posts

21 December 2009 at 1:35am

Edited: 21/12/2009 1:35am

The Page method you are using requires a URLSegment, not a ClassName. http://doc.silverstripe.org/doku.php?id=built-in-page-controls#controlling_certain_pages

You want to write your own function in the Page.php controller:

Page_controller extends ... {
...
function getPageByClass($class = 'Page') {
Return DataObject::get($class);
}

Avatar
Mohammed

Community Member, 25 Posts

21 December 2009 at 11:29am

Edited: 21/12/2009 11:31am

It worked! Thanks a lot Pigeon!

Anyone else who ran into this issue...

URLSegment/page-url refers to the CMS->Content tab->Metadata:URL field. Whatever you have listed in this field for the page you are trying to refer to is the URLSegment/page-url.

The code Pigeon suggested is as follows:

mycode/Page.php


class Page_Controller extends ContentController {
...
	function getPageByClass($class = 'Page') { 
	Return DataObject::get($class); 
	}
...
}

theme/templates/Page.ss


<% control getPageByClass(ArticleHolder) %>$Title<% end_control %>

Avatar
Mohammed

Community Member, 25 Posts

21 December 2009 at 12:06pm

Is there a way to use <% control ChildrenOf(page-url) %> by ClassName?

I tried
mycode/Page.php

	function getChildrenOfByClass($class = 'ChildrenOf') { 
	Return DataObject::get($class); 
	}

themes/templates/Page.ss
<% control getChildrenOfByClass(ServicesHolder) %>
				<li><a href="$Link" title="Go to the &quot;{$Title}&quot; page" class="$LinkingMode">$MenuTitle</a></li>			
			<% end_control %>

but that didn't seem to help...

Avatar
dhensby

Community Member, 253 Posts

21 December 2009 at 12:59pm

In the controller you don't have to use the 'get' part of the method name, eg:

<% control PageByClass(ServicesHolder) %>
..
<% end_control %>

will work.

Avatar
Mohammed

Community Member, 25 Posts

21 December 2009 at 1:11pm

If you leave out the get, the site outputs/displays every page. When I keep the work get, it works perfectly.

Avatar
dhensby

Community Member, 253 Posts

21 December 2009 at 1:21pm

Odd, ok. Well, if it ain't broke...

In response to the childrenOfClass, this is a bit harder. I take it doing:

<% control PageByClass(ServicesHolder) %>
<% control Children %>
..
<% end_control %>
<% end_control %>

is not satisfactory.

Your method just does the same as my original code... you have simply changed the optional parameter to one that will fail if none is passed.

To get the Children of a class will be quite difficult, a fairly unclean and inefficient way would be like so:

Class Page_Conroller extends ContentController {
...
function getChildrenOfByClass($class = 'Page') {
    $allPages = DataObject::get($class);
    if ($allPages->exists()) {
        $filter = '';
        foreach ($allPages as $page) {
            if ($filter) {
                $filter .= ' OR ';
            }
            $filter .= 'ParentID = ' . $page->ID;
        }
        return DataObject::get('Page',$filter);
    }
}
...
}

Incase it isn't clear, here is what is going on:
Fetch all of the pages that are of the class type you have asked for, then it fetches all the pages that are children of these pages.

This is untested code, but should be alright.

Avatar
Mohammed

Community Member, 25 Posts

21 December 2009 at 1:36pm

That works great! Once again, thank you.

The reason I wanted to do it this way (call the page by the ClassName, AKA ArticleHolder, ServicesHolder): If I used the regular URLSegment method (<% Control Page() %>) and place the code in the template file and someone decides to change the URLSegment/address, then the link in the template file will no longer work.

If I use the ClassName method, then the link will work, regardless if someone changes the URLSegment/address or not.

Thanks for all your help Pigeon!

Go to Top