Skip to content

Commit

Permalink
Merge pull request #227 from hydephp/improve-router
Browse files Browse the repository at this point in the history
Improve relative link helpers
  • Loading branch information
caendesilva authored Jul 15, 2022
2 parents e17efa8 + 3882d53 commit c08a05a
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/framework/resources/views/layouts/head.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<title>{{ isset($title) ? config('hyde.name', 'HydePHP') . ' - ' . $title : config('hyde.name', 'HydePHP') }}</title>

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

{{-- App Meta Tags --}}
Expand Down
4 changes: 2 additions & 2 deletions packages/framework/resources/views/layouts/scripts.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
@unless(Asset::hasMediaFile('hyde.js'))
<script defer src="{{ Asset::cdnLink('hyde.js') }}"></script>
@else
<script defer src="{{ Hyde::relativeLink('media/hyde.js', $currentPage) }}"></script>
<script defer src="{{ Hyde::relativeLink('media/hyde.js') }}"></script>
@endunless

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

{{-- Add any extra scripts to include before the closing <body> tag --}}
Expand Down
4 changes: 2 additions & 2 deletions packages/framework/resources/views/layouts/styles.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
@unless(Asset::hasMediaFile('hyde.css'))
<link rel="stylesheet" href="{{ Asset::cdnLink('hyde.css') }}">
@else
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/hyde.css', $currentPage) }}">
<link rel="stylesheet" href="{{ Hyde::relativeLink('media/hyde.css') }}">
@endunless

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

{{-- Add any extra styles to include after the others --}}
Expand Down
41 changes: 37 additions & 4 deletions packages/framework/src/Concerns/Internal/FileHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/framework/src/Contracts/RouteContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions packages/framework/src/Contracts/RouteFacadeContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions packages/framework/src/Facades/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ public static function all(): Collection
{
return RouteModel::all();
}

/** @inheritDoc */
public static function current(): RouteModel
{
return RouteModel::current();
}
}
10 changes: 5 additions & 5 deletions packages/framework/src/Models/NavItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions packages/framework/src/Models/NavigationMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
}
10 changes: 8 additions & 2 deletions packages/framework/src/Models/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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');
}
}
1 change: 1 addition & 0 deletions packages/framework/src/StaticPageBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
6 changes: 6 additions & 0 deletions packages/framework/tests/Feature/RouteFacadeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
22 changes: 16 additions & 6 deletions packages/framework/tests/Feature/RouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,13 @@ 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'));
$this->assertEquals(Hyde::relativeLink($route->getOutputFilePath()), $route->getLink());
$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'));
Expand All @@ -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]);
Expand All @@ -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();
}
}
5 changes: 5 additions & 0 deletions packages/framework/tests/Unit/FileHelperRelativeLinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}
}
35 changes: 35 additions & 0 deletions packages/framework/tests/Unit/HydeFileHelpersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Hyde\Framework\Testing\Unit;

use Hyde\Framework\Hyde;
use Hyde\Framework\Models\Route;
use Hyde\Testing\TestCase;

/**
* @covers \Hyde\Framework\Hyde
*/
class HydeFileHelpersTest extends TestCase
{
public function test_current_page_returns_current_page_view_property()
{
view()->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());
}
}
7 changes: 7 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Hyde\Testing;

use Hyde\Framework\Hyde;
use Hyde\Framework\Models\Pages\MarkdownPage;
use Hyde\Framework\Models\Route;
use LaravelZero\Framework\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
Expand Down Expand Up @@ -57,4 +59,9 @@ protected function tearDown(): void
{
parent::tearDown();
}

protected function mockRoute()
{
view()->share('currentRoute', (new Route(new MarkdownPage())));
}
}

0 comments on commit c08a05a

Please sign in to comment.