From 29377112c2967cfbbfd4391f033bf30344600087 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 15 Jul 2022 18:21:19 +0000 Subject: [PATCH] Merge pull request #227 from hydephp/improve-router Improve relative link helpers https://github.com/hydephp/develop/commit/c08a05a8205cc3f8bcddf8c44466a51b818b2254 --- resources/views/layouts/head.blade.php | 2 +- resources/views/layouts/scripts.blade.php | 4 +-- resources/views/layouts/styles.blade.php | 4 +-- src/Concerns/Internal/FileHelpers.php | 41 ++++++++++++++++++++--- src/Contracts/RouteContract.php | 4 +-- src/Contracts/RouteFacadeContract.php | 5 +++ src/Facades/Route.php | 6 ++++ src/Models/NavItem.php | 10 +++--- src/Models/NavigationMenu.php | 4 +-- src/Models/Route.php | 10 ++++-- src/StaticPageBuilder.php | 1 + tests/Feature/RouteFacadeTest.php | 6 ++++ tests/Feature/RouteTest.php | 22 ++++++++---- tests/Unit/FileHelperRelativeLinkTest.php | 5 +++ tests/Unit/HydeFileHelpersTest.php | 35 +++++++++++++++++++ 15 files changed, 133 insertions(+), 26 deletions(-) create mode 100644 tests/Unit/HydeFileHelpersTest.php diff --git a/resources/views/layouts/head.blade.php b/resources/views/layouts/head.blade.php index 529d6ca9..15170d39 100644 --- a/resources/views/layouts/head.blade.php +++ b/resources/views/layouts/head.blade.php @@ -3,7 +3,7 @@ {{ isset($title) ? config('hyde.name', 'HydePHP') . ' - ' . $title : config('hyde.name', 'HydePHP') }} @if (file_exists(Hyde::path('_media/favicon.ico'))) - + @endif {{-- App Meta Tags --}} diff --git a/resources/views/layouts/scripts.blade.php b/resources/views/layouts/scripts.blade.php index d44c50bb..5a39809b 100644 --- a/resources/views/layouts/scripts.blade.php +++ b/resources/views/layouts/scripts.blade.php @@ -2,12 +2,12 @@ @unless(Asset::hasMediaFile('hyde.js')) @else - + @endunless {{-- The compiled Laravel Mix scripts --}} @if(Asset::hasMediaFile('app.js')) - + @endif {{-- Add any extra scripts to include before the closing tag --}} diff --git a/resources/views/layouts/styles.blade.php b/resources/views/layouts/styles.blade.php index 73fe93a3..a33133bd 100644 --- a/resources/views/layouts/styles.blade.php +++ b/resources/views/layouts/styles.blade.php @@ -2,12 +2,12 @@ @unless(Asset::hasMediaFile('hyde.css')) @else - + @endunless {{-- The compiled Tailwind/App styles --}} @if(Asset::hasMediaFile('app.css')) - + @endif {{-- Add any extra styles to include after the others --}} diff --git a/src/Concerns/Internal/FileHelpers.php b/src/Concerns/Internal/FileHelpers.php index cebaf874..34be1f7c 100644 --- a/src/Concerns/Internal/FileHelpers.php +++ b/src/Concerns/Internal/FileHelpers.php @@ -2,7 +2,9 @@ namespace Hyde\Framework\Concerns\Internal; +use Hyde\Framework\Contracts\RouteContract; use Hyde\Framework\Models\Pages\DocumentationPage; +use Illuminate\Support\Facades\View; /** * Offloads file helper methods for the Hyde Facade. @@ -73,14 +75,24 @@ public static function pageLink(string $destination): string /** * Inject the proper number of `../` before the links in Blade templates. * - * @see \Hyde\Framework\Testing\Unit\FileHelperRelativeLinkTest + * Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View. * * @param string $destination relative to output directory on compiled site - * @param string $current the current URI path relative to the site root + * @param string|null $current the current URI path relative to the site root * @return string + * + * @see \Hyde\Framework\Testing\Unit\FileHelperRelativeLinkTest */ - public static function relativeLink(string $destination, string $current = ''): string + public static function relativeLink(string $destination, ?string $current = null): string { + if (str_starts_with($destination, '../')) { + return $destination; + } + + if ($current === null) { + $current = static::currentPage(); + } + $nestCount = substr_count($current, '/'); $route = ''; if ($nestCount > 0) { @@ -91,11 +103,32 @@ public static function relativeLink(string $destination, string $current = ''): return str_replace('//', '/', $route); } + /** + * Get the current page path, or fall back to the root path. + */ + public static function currentPage(): string + { + return View::shared('currentPage', ''); + } + + /** + * Get the current page route, or fall back to null. + */ + public static function currentRoute(): ?RouteContract + { + return View::shared('currentRoute'); + } + /** * Gets a relative web link to the given image stored in the _site/media folder. + * Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View. */ - public static function image(string $name, string $current = ''): string + public static function image(string $name, string $current = null): string { + if ($current === null) { + $current = static::currentPage(); + } + if (str_starts_with($name, 'http')) { return $name; } diff --git a/src/Contracts/RouteContract.php b/src/Contracts/RouteContract.php index 0091d8cb..2bcceb29 100644 --- a/src/Contracts/RouteContract.php +++ b/src/Contracts/RouteContract.php @@ -57,13 +57,13 @@ public function getOutputFilePath(): string; /** * Resolve a site web link to the file, using pretty URLs if enabled. * - * @param string $currentPage The current page path, or blank to get use the site root as base. * @return string Relative path to the page */ - public function getLink(string $currentPage = ''): string; + public function getLink(): string; /** * Cast a route object into a string that can be used in a href attribute. + * Should be the same as getLink(). */ public function __toString(): string; } diff --git a/src/Contracts/RouteFacadeContract.php b/src/Contracts/RouteFacadeContract.php index a9082743..1566253d 100644 --- a/src/Contracts/RouteFacadeContract.php +++ b/src/Contracts/RouteFacadeContract.php @@ -59,4 +59,9 @@ public static function getFromModel(PageContract $page): RouteContract; * @return \Illuminate\Support\Collection<\Hyde\Framework\Contracts\RouteContract> */ public static function all(): Collection; + + /** + * Get the current route for the page being rendered. + */ + public static function current(): RouteContract; } diff --git a/src/Facades/Route.php b/src/Facades/Route.php index bde8e17b..0f1aa329 100644 --- a/src/Facades/Route.php +++ b/src/Facades/Route.php @@ -42,4 +42,10 @@ public static function all(): Collection { return RouteModel::all(); } + + /** @inheritDoc */ + public static function current(): RouteModel + { + return RouteModel::current(); + } } diff --git a/src/Models/NavItem.php b/src/Models/NavItem.php index 0e241681..ff1822b7 100644 --- a/src/Models/NavItem.php +++ b/src/Models/NavItem.php @@ -72,15 +72,15 @@ public static function toRoute(RouteContract $route, string $title, int $priorit /** * Resolve a link to the navigation item. - * - * @param string $currentPage - * @return string */ - public function resolveLink(string $currentPage = ''): string + public function resolveLink(): string { - return $this->href ?? $this->route->getLink($currentPage); + return $this->href ?? $this->route->getLink(); } + /** + * Resolve a link to the navigation item. + */ public function __toString(): string { return $this->resolveLink(); diff --git a/src/Models/NavigationMenu.php b/src/Models/NavigationMenu.php index 9bfeb82e..5db0bb0e 100644 --- a/src/Models/NavigationMenu.php +++ b/src/Models/NavigationMenu.php @@ -68,8 +68,8 @@ public function sort(): self } /** @internal */ - public function getHomeLink(string $currentPage): string + public function getHomeLink(): string { - return Route::get('index')->getLink($currentPage); + return Route::get('index'); } } diff --git a/src/Models/Route.php b/src/Models/Route.php index a56db00f..f08c8b0f 100644 --- a/src/Models/Route.php +++ b/src/Models/Route.php @@ -67,9 +67,9 @@ public function getOutputFilePath(): string } /** @inheritDoc */ - public function getLink(string $currentPage = ''): string + public function getLink(): string { - return Hyde::relativeLink($this->getOutputFilePath(), $currentPage); + return Hyde::relativeLink($this->getOutputFilePath()); } /** @inheritDoc */ @@ -114,4 +114,10 @@ public static function all(): Collection { return Router::getInstance()->getRoutes(); } + + /** @inheritDoc */ + public static function current(): static + { + return Hyde::currentRoute() ?? throw new RouteNotFoundException('current'); + } } diff --git a/src/StaticPageBuilder.php b/src/StaticPageBuilder.php index 798a1ce0..760a59d0 100644 --- a/src/StaticPageBuilder.php +++ b/src/StaticPageBuilder.php @@ -41,6 +41,7 @@ public function __invoke() { view()->share('page', $this->page); view()->share('currentPage', $this->page->getCurrentPagePath()); + view()->share('currentRoute', $this->page->getRoute()); $this->needsDirectory(static::$outputPath); $this->needsDirectory(Hyde::getSiteOutputPath($this->page::getOutputDirectory())); diff --git a/tests/Feature/RouteFacadeTest.php b/tests/Feature/RouteFacadeTest.php index 71fd2fd0..47cc5b3b 100644 --- a/tests/Feature/RouteFacadeTest.php +++ b/tests/Feature/RouteFacadeTest.php @@ -41,4 +41,10 @@ public function test_route_facade_all_method_calls_all_method() { $this->assertEquals(BaseRoute::all(), Route::all()); } + + public function test_route_facade_current_method_calls_current_method() + { + $this->mockRoute(); + $this->assertEquals(BaseRoute::current(), Route::current()); + } } diff --git a/tests/Feature/RouteTest.php b/tests/Feature/RouteTest.php index 165f069c..b8982e71 100644 --- a/tests/Feature/RouteTest.php +++ b/tests/Feature/RouteTest.php @@ -135,7 +135,6 @@ public function test_route_facade_all_method_returns_all_routes() $this->assertEquals(Router::getInstance()->getRoutes(), Route::all()); } - // test getLink uses hyde::relativeLink() to get the correct path for root pages public function test_get_link_returns_correct_path_for_root_pages() { $route = new Route(new MarkdownPage(slug: 'foo')); @@ -143,7 +142,6 @@ public function test_get_link_returns_correct_path_for_root_pages() $this->assertEquals('foo.html', $route->getLink()); } - // test getLink uses hyde::relativeLink() to get the correct path for nested pages public function test_get_link_returns_correct_path_for_nested_pages() { $route = new Route(new MarkdownPage(slug: 'foo/bar')); @@ -154,11 +152,11 @@ public function test_get_link_returns_correct_path_for_nested_pages() public function test_get_link_returns_correct_path_for_nested_current_page() { $route = new Route(new MarkdownPage(slug: 'foo')); - $this->assertEquals(Hyde::relativeLink($route->getOutputFilePath(), 'foo/bar'), $route->getLink('foo/bar')); - $this->assertEquals('../foo.html', $route->getLink('foo/bar')); + view()->share('currentPage', 'foo/bar'); + $this->assertEquals(Hyde::relativeLink($route->getOutputFilePath(), 'foo/bar'), $route->getLink()); + $this->assertEquals('../foo.html', $route->getLink()); } - // test getLink returns pretty url if enabled public function test_get_link_returns_pretty_url_if_enabled() { config(['hyde.pretty_urls' => true]); @@ -167,10 +165,22 @@ public function test_get_link_returns_pretty_url_if_enabled() $this->assertEquals('foo', $route->getLink()); } - // test to string is alias for getLink public function test_to_string_is_alias_for_get_link() { $route = new Route(new MarkdownPage(slug: 'foo')); $this->assertEquals($route->getLink(), (string) $route); } + + public function test_current_returns_current_route() + { + $route = new Route(new MarkdownPage(slug: 'foo')); + view()->share('currentRoute', $route); + $this->assertEquals($route, Route::current()); + } + + public function test_current_throws_exception_if_route_is_not_found() + { + $this->expectException(RouteNotFoundException::class); + Route::current(); + } } diff --git a/tests/Unit/FileHelperRelativeLinkTest.php b/tests/Unit/FileHelperRelativeLinkTest.php index a8770cb2..36039cff 100644 --- a/tests/Unit/FileHelperRelativeLinkTest.php +++ b/tests/Unit/FileHelperRelativeLinkTest.php @@ -97,4 +97,9 @@ public function test_helper_rewrites_documentation_page_index_when_using_pretty_ $this->assertEquals('../docs/', Hyde::relativeLink('docs/index.html', 'foo/bar.html')); $this->assertEquals('../docs/', Hyde::relativeLink('docs/index.html', 'docs/foo.html')); } + + public function test_helper_does_not_rewrite_already_processed_links() + { + $this->assertEquals('../foo', Hyde::relativeLink('../foo', 'foo/bar.html')); + } } diff --git a/tests/Unit/HydeFileHelpersTest.php b/tests/Unit/HydeFileHelpersTest.php new file mode 100644 index 00000000..71afd861 --- /dev/null +++ b/tests/Unit/HydeFileHelpersTest.php @@ -0,0 +1,35 @@ +share('currentPage', 'foo'); + $this->assertEquals('foo', Hyde::currentPage()); + } + + public function test_current_page_falls_back_to_empty_string_if_current_page_view_property_is_not_set() + { + $this->assertEquals('', Hyde::currentPage()); + } + + public function test_current_route_returns_current_route_view_property() + { + view()->share('currentRoute', Route::get('index')); + $this->assertEquals(Route::get('index'), Hyde::currentRoute()); + } + + public function test_current_route_falls_back_to_null_if_current_route_view_property_is_not_set() + { + $this->assertNull(Hyde::currentRoute()); + } +}