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   1789 Views

Avatar
Tama

13 July 2010 at 10:56am Community Member, 130 Posts

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

13 July 2010 at 12:13pm Community Member, 181 Posts

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

13 July 2010 at 12:27pm Community Member, 130 Posts

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

13 July 2010 at 12:45pm Forum Moderator, 5511 Posts

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

13 July 2010 at 12:49pm (Last edited: 13 July 2010 12:50pm), Community Member, 181 Posts

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

13 July 2010 at 12:51pm Community Member, 130 Posts

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