Ancestor and Inherited functions for Page & Pages (#1362)

* Ancestor and inherited functions for Page & Pages

Addes both helper methods to `Grav\Common\Page` and Grav instance utility functions to `Grav\Common\Pages`.

* Ancestor Page return considering field criteria

* Updates according to code review issue

Made changes to act on current Page object only for the Page functions

Changed variable name to better reflect the intention of the passed param for the Pages class functions

* Simplify duplicate code

* Simplify Pages logic

Simpilfied duplicate code. Also clarified  variable naming for similar functions.
This commit is contained in:
Josh Weiss
2017-04-10 11:00:58 -07:00
committed by Andy Miller
parent bfb6b6d68a
commit 082d4e3435
2 changed files with 142 additions and 13 deletions

View File

@@ -2282,6 +2282,74 @@ class Page
}
}
/**
* Helper method to return an ancestor page.
*
* @param string $url The url of the page
* @param bool $lookup Name of the parent folder
*
* @return \Grav\Common\Page\Page page you were looking for if it exists
*/
public function ancestor($lookup = null)
{
/** @var Pages $pages */
$pages = Grav::instance()['pages'];
return $pages->ancestor($this->route, $lookup);
}
/**
* Helper method to return an ancestor page to inherit from. The current
* page object is returned.
*
* @param string $field Name of the parent folder
*
* @return Page
*/
public function inherited($field)
{
list($inherited, $currentParams) = $this->getInheritedParams($field);
$this->modifyHeader($field, $currentParams);
return $inherited;
}
/**
* Helper method to return an ancestor field only to inherit from. The
* first occurrence of an ancestor field will be returned if at all.
*
* @param string $field Name of the parent folder
*
* @return array
*/
public function inheritedField($field)
{
list($inherited, $currentParams) = $this->getInheritedParams($field);
return $currentParams;
}
/**
* Method that contains shared logic for inherited() and inheritedField()
*
* @param string $field Name of the parent folder
*
* @return array
*/
protected function getInheritedParams($field)
{
$pages = Grav::instance()['pages'];
/** @var Pages $pages */
$inherited = $pages->inherited($this->route, $field);
$inheritedParams = (array) $inherited->value('header.' . $field);
$currentParams = (array) $this->value('header.' . $field);
if($inheritedParams && is_array($inheritedParams)) {
$currentParams = array_replace_recursive($inheritedParams, $currentParams);
}
return [$inherited, $currentParams];
}
/**
* Helper method to return a page.
*

View File

@@ -291,37 +291,82 @@ class Pages
return new Collection($children, [], $this);
}
/**
* Get a page ancestor.
*
* @param string $route The relative URL of the page
* @param string $path The relative path of the ancestor folder
*
* @return Page|null
*/
public function ancestor($route, $path = null)
{
if (!is_null($path)) {
$page = $this->getPage($route);
if ($page->path() == $path) {
return $page;
} elseif (!$page->parent()->root()) {
return $this->ancestor($page->parent()->route(), $path);
}
}
return null;
}
/**
* Get a page ancestor trait.
*
* @param string $route The relative route of the page
* @param string $field The field name of the ancestor to query for
*
* @return Page|null
*/
public function inherited($route, $field = null)
{
if (!is_null($field)) {
$page = $this->getPage($route);
$ancestorField = $page->parent()->value('header.' . $field);
if ($ancestorField != null) {
return $page->parent();
} elseif (!$page->parent()->root()) {
return $this->inherited($page->parent()->route(), $field);
}
}
return null;
}
/**
* alias method to return find a page.
*
* @param string $url The relative URL of the page
* @param string $route The relative URL of the page
* @param bool $all
*
* @return Page|null
*/
public function find($url, $all = false)
public function find($route, $all = false)
{
return $this->dispatch($url, $all, false);
return $this->dispatch($route, $all, false);
}
/**
* Dispatch URI to a page.
*
* @param string $url The relative URL of the page
* @param string $route The relative URL of the page
* @param bool $all
*
* @param bool $redirect
* @return Page|null
* @throws \Exception
*/
public function dispatch($url, $all = false, $redirect = true)
public function dispatch($route, $all = false, $redirect = true)
{
// Fetch page if there's a defined route to it.
$page = isset($this->routes[$url]) ? $this->get($this->routes[$url]) : null;
// Try without trailing slash
if (!$page && Utils::endsWith($url, '/')) {
$page = isset($this->routes[rtrim($url, '/')]) ? $this->get($this->routes[rtrim($url, '/')]) : null;
}
$page = $this->getPage($route);
// Are we in the admin? this is important!
$not_admin = !isset($this->grav['admin']);
@@ -340,13 +385,13 @@ class Pages
$config = $this->grav['config'];
// See if route matches one in the site configuration
$route = $config->get("site.routes.{$url}");
$route = $config->get("site.routes.{$route}");
if ($route) {
$page = $this->dispatch($route, $all);
} else {
// Try Regex style redirects
$uri = $this->grav['uri'];
$source_url = $url;
$source_url = $route;
$extension = $uri->extension();
if (isset($extension) && !Utils::endsWith($uri->url(), $extension)) {
$source_url.= '.' . $extension;
@@ -389,6 +434,22 @@ class Pages
return $page;
}
/**
* Retrieve page instance based on the route
*
* @return Page
*/
protected function getPage($route) {
// Fetch page if there's a defined route to it.
$page = isset($this->routes[$route]) ? $this->get($this->routes[$route]) : null;
// Try without trailing slash
if (!$page && Utils::endsWith($route, '/')) {
$page = isset($this->routes[rtrim($route, '/')]) ? $this->get($this->routes[rtrim($route, '/')]) : null;
}
return $page;
}
/**
* Get root page.
*