diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 7714834bf..2d132f42b 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -113,33 +113,9 @@ class Grav extends Container $page = $pages->dispatch($path); if (!$page || !$page->routable()) { - $path_parts = pathinfo($path); - $page = $c['pages']->dispatch($path_parts['dirname'], true); - if ($page) { - $media = $page->media()->all(); - $parsed_url = parse_url(urldecode($uri->basename())); - - $media_file = $parsed_url['path']; - - // if this is a media object, try actions first - if (isset($media[$media_file])) { - $medium = $media[$media_file]; - foreach ($uri->query(null, true) as $action => $params) { - if (in_array($action, ImageMedium::$magic_actions)) { - call_user_func_array(array(&$medium, $action), explode(',', $params)); - } - } - Utils::download($medium->path(), false); - } else { - $download = true; - // little work-around to ensure .css and .js files are always sent inline not downloaded - if (Utils::endsWith($uri->basename(), ['.css', '.js'])) { - $download = false; - } - Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download); - } - } + // Try fallback URL stuff... + $c->fallbackUrl($page, $path); // If no page found, fire event $event = $c->fireEvent('onPageNotFound'); @@ -398,4 +374,46 @@ class Grav extends Container $this->fireEvent('onShutdown'); } + + /** + * This attempts to fine media, other files, and download them + * @param $page + * @param $path + */ + protected function fallbackUrl($page, $path) + { + /** @var Uri $uri */ + $uri = $this['uri']; + + $path_parts = pathinfo($path); + $page = $this['pages']->dispatch($path_parts['dirname'], true); + if ($page) { + $media = $page->media()->all(); + + $parsed_url = parse_url(urldecode($uri->basename())); + + $media_file = $parsed_url['path']; + + // if this is a media object, try actions first + if (isset($media[$media_file])) { + $medium = $media[$media_file]; + foreach ($uri->query(null, true) as $action => $params) { + if (in_array($action, ImageMedium::$magic_actions)) { + call_user_func_array(array(&$medium, $action), explode(',', $params)); + } + } + Utils::download($medium->path(), false); + } + + // has an extension, try to download it... + if (isset($path_parts['extension'])) { + $download = true; + // little work-around to ensure .css and .js files are always sent inline not downloaded + if (in_array($path_parts['extension'], ['.css', '.js'])) { + $download = false; + } + Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download); + } + } + } } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 83a73a074..740e2ee06 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1108,31 +1108,37 @@ class Page /** * Gets the url for the Page. * - * @param bool $include_host Defaults false, but true would include http://yourhost.com - * @return string The url. + * @param bool $include_host Defaults false, but true would include http://yourhost.com + * @param bool $canonical true to return the canonical URL + * + * @return string The url. */ - public function url($include_host = false) + public function url($include_host = false, $canonical = false) { - if (empty($this->url)) { - /** @var Pages $pages */ - $pages = self::getGrav()['pages']; - /** @var Uri $uri */ - $uri = self::getGrav()['uri']; + /** @var Pages $pages */ + $pages = self::getGrav()['pages']; - $rootUrl = $uri->rootUrl($include_host) . $pages->base(); - $url = $rootUrl.'/'.trim($this->route(), '/'); - - // trim trailing / if not root - if ($url !== '/') { - $url = rtrim($url, '/'); - } - - $this->url = $url; + // get canonical route if requested + if ($canonical) { + $route = $this->routeCanonical(); + } else { + $route = $this->route(); } + /** @var Uri $uri */ + $uri = self::getGrav()['uri']; - return $this->url; + $rootUrl = $uri->rootUrl($include_host) . $pages->base(); + + $url = $rootUrl.'/'.trim($route, '/'); + + // trim trailing / if not root + if ($url !== '/') { + $url = rtrim($url, '/'); + } + + return $url; } /** @@ -1184,6 +1190,27 @@ class Page } } + /** + * Gets the canonical route for this page if its set. If provided it will use + * that value, else if it's `true` it will use the default route. + * + * @param null $var + * + * @return bool|string + */ + public function routeCanonical($var = null) + { + if ($var != null) { + $this->routes['canonical'] = (array)$var; + } + + if (!empty($this->routes) && isset($this->routes['canonical'])) { + return $this->routes['canonical']; + } + + return $this->route(); + } + /** * Gets and sets the identifier for this Page object. * diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 04c4af901..d927b8a25 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -638,7 +638,14 @@ class Pages $taxonomy->addTaxonomy($page); // add route - $this->routes[$page->route()] = $page->path(); + $route = $page->route(); + $this->routes[$route] = $page->path(); + + // add canonical + $route_canonical = $page->routeCanonical(); + if ($route_canonical && ($route !== $route_canonical)) { + $this->routes[$route_canonical] = $page->path(); + } // add aliases to routes list if they are provided $route_aliases = $page->routeAliases();