Reputation: 4424
I want to get all of the SiteTree pages of a Silverstripe website and then sort them by depth descending. By depth I mean the number of parents they have.
This is already done to some extent by the Google Sitemaps Module. Except it doesn't go past a depth of 10 and doesn't calculate for pages hidden from search: https://github.com/silverstripe-labs/silverstripe-googlesitemaps
Looking at the Google Sitemaps Module module it appears easy enough to count the number of parents of a page: ( /code/GoogleSitemapDecorator.php - line 78)
$parentStack = $this->owner->parentStack();
$numParents = is_array($parentStack) ? count($parentStack) - 1: 0;
But what is the best way to sort the SiteTree using this calculation?
I'm hoping there's an easier way than getting all of the SiteTree, appending the depth, and then resorting.
Upvotes: 1
Views: 878
Reputation: 316
If you're using PostgreSQL you can also use a single database query. In our effort to speed up SilverStripe (2.4), we've replaced the getSiteTreeFor()
with a single database query, see:
http://fvue.nl/wiki/SilverStripe:_Replace_getSiteTreeFor_with_single_query
The breadcrumb
field contains an array of ID's on which you can sort.
Upvotes: 0
Reputation: 381
The function below will get all published pages from the database, checks they are viewable and not an error page, finds out how many ancestors they have and then returns a DataObjectSet of the pages ordered by depth (number of ancestors).
public function CustomPages() {
$filter = '';
$pages = Versioned::get_by_stage('SiteTree', 'Live', $filter);
$custom_pages = new DataObjectSet();
if($pages) {
foreach($pages as $page) {
if( $page->canView() && !($page instanceof ErrorPage) ) {
$parentStack = $page->parentStack();
$numParents = is_array($parentStack) ? count($parentStack) - 1 : 0;
$page->Depth = $numParents;
$custom_pages->push($page);
}
}
}
$custom_pages->sort('Depth', 'DESC');
return $custom_pages;
}
Upvotes: 3