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.

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

How to count all Children of a page? Including those not shown in menus


Go to End


6 Posts   2812 Views

Avatar
Tama

Community Member, 138 Posts

13 July 2010 at 10:56am

Hi there

I'm writing a function which has to work out how many children a page has. I started off with this code:

	public function numChildren()
	{
		$children = $this->Children();
		return $children->Count();
	}

However this doesn't count the child pages that have "Show in menus" unticked.

Does anyone have a simple solution to this?

Cheers
Tama

Avatar
TotalNet

Community Member, 181 Posts

13 July 2010 at 12:13pm

Have you tried $this->AllChildren() ?

That should do the trick.

There's not much in the docs but you can use $AllChildren.Count directly in the template if all you want to do is output the number

hth

Rich

Avatar
Tama

Community Member, 138 Posts

13 July 2010 at 12:27pm

Excellent, that was exactly what I was after - thank you Rich.

What I am doing it putting in a RSS link on every page (picked up by modern browsers) but if the page hasn't got any children it points back to the parent page RSS link.

class Page_Controller extends ContentController {
	public function init() {
		parent::init();
		
		//Display RSS link on every page with children. If no children display parent RSS link
		if($this->numChildren()>0){
			RSSFeed::linkToFeed($this->Link() . "rss");	
		} else {
			RSSFeed::linkToFeed($this->Parent()->Link() . "rss");	
		}
	}
	
	public function numChildren()
	{
		$children = $this->AllChildren();
		return $children->Count();
	}

	function rss() {
		$rss = new RSSFeed($this->Children(), $this->Link(), $this->Title." RSS Feed");
		$rss->outputToBrowser();
	}

Avatar
Willr

Forum Moderator, 5523 Posts

13 July 2010 at 12:45pm

As a little note using $this->AllChildren()->Count is quite slow since it has to build a whole set of the pages just to get the count. If you are worried about performance then a direct count db query would be much faster. Like DB::query("SELECT COUNT(*) FROM SiteTree_Live WHERE ParentID = '$this->ID'")->value();

Avatar
TotalNet

Community Member, 181 Posts

13 July 2010 at 12:49pm

Edited: 13/07/2010 12:50pm

Glad to help.

In that case you can save yourself a function and just put:

...
if ($this->AllChildren()->Count()>0) {
...

a word of warning on using "Show in Menus", Google site maps uses this as an extra selector for deciding whether to include the page in sitemap.xml - just something to consider :)

Rich

EDIT: or use Willr's snippet ;)

Avatar
Tama

Community Member, 138 Posts

13 July 2010 at 12:51pm

Thanks again - I might take Will's advice and go for the direct SQL query. Speed is good.