From 1e9418b87bad5b3f659b1135df021ec89b6e46c3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 30 Jun 2015 14:59:24 -0600 Subject: [PATCH 1/4] add canonical route support --- system/src/Grav/Common/Page/Page.php | 63 ++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 18 deletions(-) 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. * From 1a91cf7033f16392963347712904dd780bb65edd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 30 Jun 2015 14:59:48 -0600 Subject: [PATCH 2/4] add canonical routes like an alias --- system/src/Grav/Common/Page/Pages.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 7de8bda10..3f81dda5f 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -631,7 +631,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(); From 2b6740dc7ba4d273b68dfa645f78b6d261084bc7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 30 Jun 2015 16:14:06 -0600 Subject: [PATCH 3/4] fix for content mismatch error --- system/src/Grav/Common/Grav.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 97082402b..4379ee011 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -125,10 +125,13 @@ class Grav extends Container } } Utils::download($medium->path(), false); - } else { + } + + // 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 (Utils::endsWith($uri->basename(), ['.css', '.js'])) { + if (in_array($path_parts['extension'], ['.css', '.js'])) { $download = false; } Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download); From 547f72919f96b7b9cd7a2b7feaf479b035becd44 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 30 Jun 2015 16:22:43 -0600 Subject: [PATCH 4/4] broke-out fallback into a protected method --- system/src/Grav/Common/Grav.php | 73 ++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 4379ee011..f495f9431 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -107,36 +107,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); - } - - // 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); - } - } + // Try fallback URL stuff... + $c->fallbackUrl($page, $path); // If no page found, fire event $event = $c->fireEvent('onPageNotFound'); @@ -395,4 +368,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); + } + } + } }