* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ trait HasChildren { /** * The list of available published children */ public Pages|null $children = null; /** * The list of available draft children */ public Pages|null $drafts = null; /** * The combined list of available published * and draft children */ public Pages|null $childrenAndDrafts = null; /** * Returns all published children */ public function children(): Pages { return $this->children ??= Pages::factory($this->inventory()['children'], $this); } /** * Returns all published and draft children at the same time */ public function childrenAndDrafts(): Pages { return $this->childrenAndDrafts ??= $this->children()->merge($this->drafts()); } /** * Searches for a draft child by ID */ public function draft(string $path): Page|null { $path = str_replace('_drafts/', '', $path); if (Str::contains($path, '/') === false) { return $this->drafts()->find($path); } $parts = explode('/', $path); $parent = $this; foreach ($parts as $slug) { if ($page = $parent->find($slug)) { $parent = $page; continue; } if ($draft = $parent->drafts()->find($slug)) { $parent = $draft; continue; } return null; } return $parent; } /** * Returns all draft children */ public function drafts(): Pages { if ($this->drafts instanceof Pages) { return $this->drafts; } $kirby = $this->kirby(); // create the inventory for all drafts $inventory = Dir::inventory( $this->root() . '/_drafts', $kirby->contentExtension(), $kirby->contentIgnore(), $kirby->multilang() ); return $this->drafts = Pages::factory($inventory['children'], $this, true); } /** * Finds one or multiple published children by ID */ public function find(string|array ...$arguments): Page|Pages|null { return $this->children()->find(...$arguments); } /** * Finds a single published or draft child */ public function findPageOrDraft(string $path): Page|null { return $this->children()->find($path) ?? $this->drafts()->find($path); } /** * Returns a collection of all published children of published children */ public function grandChildren(): Pages { return $this->children()->children(); } /** * Checks if the model has any published children */ public function hasChildren(): bool { return $this->children()->count() > 0; } /** * Checks if the model has any draft children */ public function hasDrafts(): bool { return $this->drafts()->count() > 0; } /** * Checks if the page has any listed children */ public function hasListedChildren(): bool { return $this->children()->listed()->count() > 0; } /** * Checks if the page has any unlisted children */ public function hasUnlistedChildren(): bool { return $this->children()->unlisted()->count() > 0; } /** * Creates a flat child index * * @param bool $drafts If set to `true`, draft children are included */ public function index(bool $drafts = false): Pages { if ($drafts === true) { return $this->childrenAndDrafts()->index($drafts); } return $this->children()->index(); } /** * Sets the published children collection * * @return $this */ protected function setChildren(array|null $children = null): static { if ($children !== null) { $this->children = Pages::factory($children, $this); } return $this; } /** * Sets the draft children collection * * @return $this */ protected function setDrafts(array|null $drafts = null): static { if ($drafts !== null) { $this->drafts = Pages::factory($drafts, $this, true); } return $this; } }