silverstripe-framework/docs/en/02_Developer_Guides/00_Model/02_SiteTree.md

6.0 KiB

Sitetree

Introduction

Basic data-object representing all pages within the site tree. The omnipresent Page class (located in mysite/code/Page.php) is based on this class.

Creating, Modifying and Finding Pages

See the "datamodel" topic.

Linking

:::php
// wrong
$mylink = $mypage->URLSegment;
// right
$mylink = $mypage->Link(); // alternatively: AbsoluteLink(), RelativeLink()

In a nutshell, the nested URLs feature means that your site URLs now reflect the actual parent/child page structure of your site. The URLs map directly to the chain of parent and child pages. The below table shows a quick summary of what these changes mean for your site:

url table

Querying

Use SiteTree::get_by_link() to correctly retrieve a page by URL, as it taked nested URLs into account (a page URL might consist of more than one URLSegment).

:::php
// wrong
$mypage = SiteTree::get()->filter("URLSegment", '<mylink>')->First();
// right
$mypage = SiteTree::get_by_link('<mylink>');

Versioning

The SiteTree class automatically has an extension applied to it: [Versioned](api:Versioned). This provides the basis for the CMS to operate on different stages, and allow authors to save their changes without publishing them to website visitors straight away. Versioned is a generic extension which can be applied to any DataObject, so most of its functionality is explained in the ["versioning" topic](/topics/versioning).

Since SiteTree makes heavy use of the extension, it adds some additional functionality and helpers on top of it.

Permission control:

:::php
class MyPage extends Page {
	public function canPublish($member = null) {
		// return boolean from custom logic
	}
	public function canDeleteFromLive($member = null) {
		// return boolean from custom logic
	}
}

Stage operations:

  • $page->doUnpublish(): removes the "Live" record, with additional permission checks, as well as special logic for VirtualPage and RedirectorPage associations
  • $page->doPublish(): Inverse of doUnpublish()
  • $page->doRevertToLive(): Reverts current record to live state (makes sense to save to "draft" stage afterwards)
  • $page->doRestoreToStage(): Restore the content in the active copy of this SiteTree page to the stage site.

Hierarchy operations (defined on [api:Hierarchy]:

  • $page->liveChildren(): Return results only from live table
  • $page->stageChildren(): Return results from the stage table
  • $page->AllHistoricalChildren(): Return all the children this page had, including pages that were deleted from both stage & live.
  • $page->AllChildrenIncludingDeleted(): Return all children, including those that have been deleted but are still in live.

Allowed Children, Default Child and Root-Level

By default, any page type can be the child of any other page type.
However, there are static properties that can be used to set up restrictions that will preserve the integrity of the page hierarchy.

Example: Restrict blog entry pages to nesting underneath their blog holder

:::php
class BlogHolder extends Page {
  // Blog holders can only contain blog entries
  private static $allowed_children = array("BlogEntry");
  private static $default_child = "BlogEntry";
  // ...
}

class BlogEntry extends Page {
  // Blog entries can't contain children
  private static $allowed_children = "none";
  private static $can_be_root = false;
  // ...
}	

class Page extends SiteTree {
  // Don't let BlogEntry pages be underneath Pages.  Only underneath Blog holders.
  private static $allowed_children = array("*Page,", "BlogHolder");
}
  • allowed_children: This can be an array of allowed child classes, or the string "none" - indicating that this page type can't have children. If a classname is prefixed by "*", such as "*Page", then only that class is allowed - no subclasses. Otherwise, the class and all its subclasses are allowed.

  • default_child: If a page is allowed more than 1 type of child, you can set a default. This is the value that will be automatically selected in the page type dropdown when you create a page in the CMS.

  • can_be_root: This is a boolean variable. It lets you specify whether the given page type can be in the top level.

Note that there is no allowed_parentscontrol. To set this, you will need to specify theallowed_children` of all other page types to exclude the page type in question.

Tree Limitations

SilverStripe limits the amount of initially rendered nodes in order to avoid processing delays, usually to a couple of dozen. The value can be configured through [api:Hierarchy::$node_threshold_total].

If a website has thousands of pages, the tree UI metaphor can become an inefficient way to manage them. The CMS has an alternative "list view" for this purpose, which allows sorting and paging through large numbers of pages in a tabular view.

To avoid exceeding performance constraints of both the server and browser, SilverStripe places hard limits on the amount of rendered pages in a specific tree leaf, typically a couple of hundred pages. The value can be configured through [api:Hierarchy::$node_threshold_leaf].

Tree Display (Description, Icons and Badges)

The page tree in the CMS is a central element to manage page hierarchies, hence its display of pages can be customized as well.

On a most basic level, you can specify a custom page icon to make it easier for CMS authors to identify pages of this type, when navigating the tree or adding a new page:

:::php
class StaffPage extends Page {
	private static $singular_name = 'Staff Directory';
	private static $plural_name = 'Staff Directories';
	private static $description = 'Two-column layout with a list of staff members';
	private static $icon = 'mysite/images/staff-icon.png';
	// ...
}

You can also add custom "badges" to each page in the tree, which denote status. Built-in examples are "Draft" and "Deleted" flags. This is detailed in the "Customize the CMS Tree" howto.