Skip to content

Commit c08a05a

Browse files
authored
Merge pull request #227 from hydephp/improve-router
Improve relative link helpers
2 parents e17efa8 + 3882d53 commit c08a05a

16 files changed

+140
-26
lines changed

packages/framework/resources/views/layouts/head.blade.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<title>{{ isset($title) ? config('hyde.name', 'HydePHP') . ' - ' . $title : config('hyde.name', 'HydePHP') }}</title>
44

55
@if (file_exists(Hyde::path('_media/favicon.ico')))
6-
<link rel="shortcut icon" href="{{ Hyde::relativeLink('media/favicon.ico', $currentPage) }}" type="image/x-icon">
6+
<link rel="shortcut icon" href="{{ Hyde::relativeLink('media/favicon.ico') }}" type="image/x-icon">
77
@endif
88

99
{{-- App Meta Tags --}}

packages/framework/resources/views/layouts/scripts.blade.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
@unless(Asset::hasMediaFile('hyde.js'))
33
<script defer src="{{ Asset::cdnLink('hyde.js') }}"></script>
44
@else
5-
<script defer src="{{ Hyde::relativeLink('media/hyde.js', $currentPage) }}"></script>
5+
<script defer src="{{ Hyde::relativeLink('media/hyde.js') }}"></script>
66
@endunless
77

88
{{-- The compiled Laravel Mix scripts --}}
99
@if(Asset::hasMediaFile('app.js'))
10-
<script defer src="{{ Hyde::relativeLink('media/app.js', $currentPage) }}"></script>
10+
<script defer src="{{ Hyde::relativeLink('media/app.js') }}"></script>
1111
@endif
1212

1313
{{-- Add any extra scripts to include before the closing <body> tag --}}

packages/framework/resources/views/layouts/styles.blade.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
@unless(Asset::hasMediaFile('hyde.css'))
33
<link rel="stylesheet" href="{{ Asset::cdnLink('hyde.css') }}">
44
@else
5-
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/hyde.css', $currentPage) }}">
5+
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/hyde.css') }}">
66
@endunless
77

88
{{-- The compiled Tailwind/App styles --}}
99
@if(Asset::hasMediaFile('app.css'))
10-
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/app.css', $currentPage) }}">
10+
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/app.css') }}">
1111
@endif
1212

1313
{{-- Add any extra styles to include after the others --}}

packages/framework/src/Concerns/Internal/FileHelpers.php

+37-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Hyde\Framework\Concerns\Internal;
44

5+
use Hyde\Framework\Contracts\RouteContract;
56
use Hyde\Framework\Models\Pages\DocumentationPage;
7+
use Illuminate\Support\Facades\View;
68

79
/**
810
* Offloads file helper methods for the Hyde Facade.
@@ -73,14 +75,24 @@ public static function pageLink(string $destination): string
7375
/**
7476
* Inject the proper number of `../` before the links in Blade templates.
7577
*
76-
* @see \Hyde\Framework\Testing\Unit\FileHelperRelativeLinkTest
78+
* Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View.
7779
*
7880
* @param string $destination relative to output directory on compiled site
79-
* @param string $current the current URI path relative to the site root
81+
* @param string|null $current the current URI path relative to the site root
8082
* @return string
83+
*
84+
* @see \Hyde\Framework\Testing\Unit\FileHelperRelativeLinkTest
8185
*/
82-
public static function relativeLink(string $destination, string $current = ''): string
86+
public static function relativeLink(string $destination, ?string $current = null): string
8387
{
88+
if (str_starts_with($destination, '../')) {
89+
return $destination;
90+
}
91+
92+
if ($current === null) {
93+
$current = static::currentPage();
94+
}
95+
8496
$nestCount = substr_count($current, '/');
8597
$route = '';
8698
if ($nestCount > 0) {
@@ -91,11 +103,32 @@ public static function relativeLink(string $destination, string $current = ''):
91103
return str_replace('//', '/', $route);
92104
}
93105

106+
/**
107+
* Get the current page path, or fall back to the root path.
108+
*/
109+
public static function currentPage(): string
110+
{
111+
return View::shared('currentPage', '');
112+
}
113+
114+
/**
115+
* Get the current page route, or fall back to null.
116+
*/
117+
public static function currentRoute(): ?RouteContract
118+
{
119+
return View::shared('currentRoute');
120+
}
121+
94122
/**
95123
* Gets a relative web link to the given image stored in the _site/media folder.
124+
* Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View.
96125
*/
97-
public static function image(string $name, string $current = ''): string
126+
public static function image(string $name, string $current = null): string
98127
{
128+
if ($current === null) {
129+
$current = static::currentPage();
130+
}
131+
99132
if (str_starts_with($name, 'http')) {
100133
return $name;
101134
}

packages/framework/src/Contracts/RouteContract.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ public function getOutputFilePath(): string;
5757
/**
5858
* Resolve a site web link to the file, using pretty URLs if enabled.
5959
*
60-
* @param string $currentPage The current page path, or blank to get use the site root as base.
6160
* @return string Relative path to the page
6261
*/
63-
public function getLink(string $currentPage = ''): string;
62+
public function getLink(): string;
6463

6564
/**
6665
* Cast a route object into a string that can be used in a href attribute.
66+
* Should be the same as getLink().
6767
*/
6868
public function __toString(): string;
6969
}

packages/framework/src/Contracts/RouteFacadeContract.php

+5
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,9 @@ public static function getFromModel(PageContract $page): RouteContract;
5959
* @return \Illuminate\Support\Collection<\Hyde\Framework\Contracts\RouteContract>
6060
*/
6161
public static function all(): Collection;
62+
63+
/**
64+
* Get the current route for the page being rendered.
65+
*/
66+
public static function current(): RouteContract;
6267
}

packages/framework/src/Facades/Route.php

+6
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ public static function all(): Collection
4242
{
4343
return RouteModel::all();
4444
}
45+
46+
/** @inheritDoc */
47+
public static function current(): RouteModel
48+
{
49+
return RouteModel::current();
50+
}
4551
}

packages/framework/src/Models/NavItem.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ public static function toRoute(RouteContract $route, string $title, int $priorit
7272

7373
/**
7474
* Resolve a link to the navigation item.
75-
*
76-
* @param string $currentPage
77-
* @return string
7875
*/
79-
public function resolveLink(string $currentPage = ''): string
76+
public function resolveLink(): string
8077
{
81-
return $this->href ?? $this->route->getLink($currentPage);
78+
return $this->href ?? $this->route->getLink();
8279
}
8380

81+
/**
82+
* Resolve a link to the navigation item.
83+
*/
8484
public function __toString(): string
8585
{
8686
return $this->resolveLink();

packages/framework/src/Models/NavigationMenu.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public function sort(): self
6868
}
6969

7070
/** @internal */
71-
public function getHomeLink(string $currentPage): string
71+
public function getHomeLink(): string
7272
{
73-
return Route::get('index')->getLink($currentPage);
73+
return Route::get('index');
7474
}
7575
}

packages/framework/src/Models/Route.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ public function getOutputFilePath(): string
6767
}
6868

6969
/** @inheritDoc */
70-
public function getLink(string $currentPage = ''): string
70+
public function getLink(): string
7171
{
72-
return Hyde::relativeLink($this->getOutputFilePath(), $currentPage);
72+
return Hyde::relativeLink($this->getOutputFilePath());
7373
}
7474

7575
/** @inheritDoc */
@@ -114,4 +114,10 @@ public static function all(): Collection
114114
{
115115
return Router::getInstance()->getRoutes();
116116
}
117+
118+
/** @inheritDoc */
119+
public static function current(): static
120+
{
121+
return Hyde::currentRoute() ?? throw new RouteNotFoundException('current');
122+
}
117123
}

packages/framework/src/StaticPageBuilder.php

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public function __invoke()
4141
{
4242
view()->share('page', $this->page);
4343
view()->share('currentPage', $this->page->getCurrentPagePath());
44+
view()->share('currentRoute', $this->page->getRoute());
4445

4546
$this->needsDirectory(static::$outputPath);
4647
$this->needsDirectory(Hyde::getSiteOutputPath($this->page::getOutputDirectory()));

packages/framework/tests/Feature/RouteFacadeTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,10 @@ public function test_route_facade_all_method_calls_all_method()
4141
{
4242
$this->assertEquals(BaseRoute::all(), Route::all());
4343
}
44+
45+
public function test_route_facade_current_method_calls_current_method()
46+
{
47+
$this->mockRoute();
48+
$this->assertEquals(BaseRoute::current(), Route::current());
49+
}
4450
}

packages/framework/tests/Feature/RouteTest.php

+16-6
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,13 @@ public function test_route_facade_all_method_returns_all_routes()
135135
$this->assertEquals(Router::getInstance()->getRoutes(), Route::all());
136136
}
137137

138-
// test getLink uses hyde::relativeLink() to get the correct path for root pages
139138
public function test_get_link_returns_correct_path_for_root_pages()
140139
{
141140
$route = new Route(new MarkdownPage(slug: 'foo'));
142141
$this->assertEquals(Hyde::relativeLink($route->getOutputFilePath()), $route->getLink());
143142
$this->assertEquals('foo.html', $route->getLink());
144143
}
145144

146-
// test getLink uses hyde::relativeLink() to get the correct path for nested pages
147145
public function test_get_link_returns_correct_path_for_nested_pages()
148146
{
149147
$route = new Route(new MarkdownPage(slug: 'foo/bar'));
@@ -154,11 +152,11 @@ public function test_get_link_returns_correct_path_for_nested_pages()
154152
public function test_get_link_returns_correct_path_for_nested_current_page()
155153
{
156154
$route = new Route(new MarkdownPage(slug: 'foo'));
157-
$this->assertEquals(Hyde::relativeLink($route->getOutputFilePath(), 'foo/bar'), $route->getLink('foo/bar'));
158-
$this->assertEquals('../foo.html', $route->getLink('foo/bar'));
155+
view()->share('currentPage', 'foo/bar');
156+
$this->assertEquals(Hyde::relativeLink($route->getOutputFilePath(), 'foo/bar'), $route->getLink());
157+
$this->assertEquals('../foo.html', $route->getLink());
159158
}
160159

161-
// test getLink returns pretty url if enabled
162160
public function test_get_link_returns_pretty_url_if_enabled()
163161
{
164162
config(['hyde.pretty_urls' => true]);
@@ -167,10 +165,22 @@ public function test_get_link_returns_pretty_url_if_enabled()
167165
$this->assertEquals('foo', $route->getLink());
168166
}
169167

170-
// test to string is alias for getLink
171168
public function test_to_string_is_alias_for_get_link()
172169
{
173170
$route = new Route(new MarkdownPage(slug: 'foo'));
174171
$this->assertEquals($route->getLink(), (string) $route);
175172
}
173+
174+
public function test_current_returns_current_route()
175+
{
176+
$route = new Route(new MarkdownPage(slug: 'foo'));
177+
view()->share('currentRoute', $route);
178+
$this->assertEquals($route, Route::current());
179+
}
180+
181+
public function test_current_throws_exception_if_route_is_not_found()
182+
{
183+
$this->expectException(RouteNotFoundException::class);
184+
Route::current();
185+
}
176186
}

packages/framework/tests/Unit/FileHelperRelativeLinkTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,9 @@ public function test_helper_rewrites_documentation_page_index_when_using_pretty_
9797
$this->assertEquals('../docs/', Hyde::relativeLink('docs/index.html', 'foo/bar.html'));
9898
$this->assertEquals('../docs/', Hyde::relativeLink('docs/index.html', 'docs/foo.html'));
9999
}
100+
101+
public function test_helper_does_not_rewrite_already_processed_links()
102+
{
103+
$this->assertEquals('../foo', Hyde::relativeLink('../foo', 'foo/bar.html'));
104+
}
100105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Hyde\Framework\Testing\Unit;
4+
5+
use Hyde\Framework\Hyde;
6+
use Hyde\Framework\Models\Route;
7+
use Hyde\Testing\TestCase;
8+
9+
/**
10+
* @covers \Hyde\Framework\Hyde
11+
*/
12+
class HydeFileHelpersTest extends TestCase
13+
{
14+
public function test_current_page_returns_current_page_view_property()
15+
{
16+
view()->share('currentPage', 'foo');
17+
$this->assertEquals('foo', Hyde::currentPage());
18+
}
19+
20+
public function test_current_page_falls_back_to_empty_string_if_current_page_view_property_is_not_set()
21+
{
22+
$this->assertEquals('', Hyde::currentPage());
23+
}
24+
25+
public function test_current_route_returns_current_route_view_property()
26+
{
27+
view()->share('currentRoute', Route::get('index'));
28+
$this->assertEquals(Route::get('index'), Hyde::currentRoute());
29+
}
30+
31+
public function test_current_route_falls_back_to_null_if_current_route_view_property_is_not_set()
32+
{
33+
$this->assertNull(Hyde::currentRoute());
34+
}
35+
}

tests/TestCase.php

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Hyde\Testing;
44

55
use Hyde\Framework\Hyde;
6+
use Hyde\Framework\Models\Pages\MarkdownPage;
7+
use Hyde\Framework\Models\Route;
68
use LaravelZero\Framework\Testing\TestCase as BaseTestCase;
79

810
abstract class TestCase extends BaseTestCase
@@ -57,4 +59,9 @@ protected function tearDown(): void
5759
{
5860
parent::tearDown();
5961
}
62+
63+
protected function mockRoute()
64+
{
65+
view()->share('currentRoute', (new Route(new MarkdownPage())));
66+
}
6067
}

0 commit comments

Comments
 (0)