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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

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


Reply


6 Posts   1813 Views

Avatar
Tama

Community Member, 130 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, 130 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, 5513 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, 130 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.