Skip to content

Commit

Permalink
Add Inertia.js support
Browse files Browse the repository at this point in the history
  • Loading branch information
inxilpro committed Oct 6, 2021
1 parent b5cb892 commit c396e01
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 4 deletions.
1 change: 0 additions & 1 deletion .idea/blade.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ format. This project adheres to [Semantic Versioning](https://semver.org/spec/v2

## [Unreleased]

## [1.3.0]

## Added

- Added support for Inertia.js

## [1.2.0]

## Added
Expand Down Expand Up @@ -70,7 +76,8 @@ format. This project adheres to [Semantic Versioning](https://semver.org/spec/v2
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

[Unreleased]: https://github.com/glhd/gretel/compare/1.2.0...HEAD
[Unreleased]: https://github.com/glhd/gretel/compare/1.3.0...HEAD
[1.3.0]: https://github.com/glhd/gretel/compare/1.2.0...1.3.0
[1.2.0]: https://github.com/glhd/gretel/compare/1.1.0...1.2.0
[1.1.0]: https://github.com/glhd/gretel/compare/1.0.0...1.1.0
[1.0.0]: https://github.com/glhd/gretel/compare/0.1.1...1.0.0
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Gretel is a Laravel package for adding route-based breadcrumbs to your applicati
- [Using a Custom Template](#custom-breadcrumb-view) (while maintaining accessibility)
- [Caching Breadcrumbs](#caching-breadcrumbs) (required if using `route:cache`)
- [Handling Errors](#handling-errors)
- [Integration With Third Party Packages](#integration-with-third-party-packages) (Inertia.js)

## Installation

Expand Down Expand Up @@ -280,3 +281,35 @@ Gretel::handleMisconfiguredBreadcrumbs(function(Throwable $exception) {
// Throw an exception locally if there's a mis-configured breadcrumb
Gretel::throwOnMisconfiguredBreadcrumbs(! App::environment('production'));
```

### Integration With Third Party Packages

Gretel automatically [shares your breadcrumbs with Inertia.js](https://inertiajs.com/shared-data)
if you have that package installed. You don't need to do anything to enable this integration. (If
you do not want this behavior for some reason, you can disable it by publishing the Gretel config.)

Your breadcrumbs will be available in your client code as `breadcrumbs` and look something like:

```js
const breadcrumbs = [
{
title: 'Home',
url: 'https://www.yourapp.com',
is_current_page: false,
},
{
title: 'Users',
url: 'https://www.yourapp.com/users',
is_current_page: false,
},
{
title: 'Add a User',
url: 'https://www.yourapp.com/users/create',
is_current_page: true,
},
];
```

You can then render the breadcrumbs in the client however you see fit. Be sure to review
the [custom breadcrumbs](#custom-breadcrumb-view) section for information about how to
ensure that your client-side breadcrumbs are fully accessible.
14 changes: 14 additions & 0 deletions config.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@

'view' => 'gretel::tailwind',

/*
|--------------------------------------------------------------------------
| Third Party Integrations
|--------------------------------------------------------------------------
|
| By default, Gretel will share the current breadcrumbs with Inertia.js
| if Inertia is installed. You can disable that here.
|
*/

'packages' => [
'inertiajs/inertia-laravel' => true,
],

/*
|--------------------------------------------------------------------------
| Use Static Closures
Expand Down
12 changes: 10 additions & 2 deletions src/Routing/RequestBreadcrumbs.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
use Illuminate\Routing\Route;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\ForwardsCalls;
use JsonSerializable;

/**
* @mixin Collection
*/
class RequestBreadcrumbs implements Arrayable, Jsonable
class RequestBreadcrumbs implements JsonSerializable, Arrayable, Jsonable
{
use ForwardsCalls;

Expand Down Expand Up @@ -56,9 +57,16 @@ public function toArray(): array
return $this->toCollection()->toArray();
}

public function jsonSerialize(): array
{
return $this->toCollection()
->map(fn(Breadcrumb $breadcrumb) => $breadcrumb->jsonSerialize())
->all();
}

public function toJson($options = JSON_THROW_ON_ERROR)
{
return json_encode($this->toArray(), $options);
return json_encode($this->jsonSerialize(), $options);
}

public function __call($name, $arguments)
Expand Down
23 changes: 23 additions & 0 deletions src/Support/GretelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
use Glhd\Gretel\Routing\RequestBreadcrumbs as RouteBreadcrumbs;
use Glhd\Gretel\View\Components\Breadcrumbs as BreadcrumbComponent;
use Illuminate\Container\Container;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Compilers\BladeCompiler;
use Inertia\Inertia;

class GretelServiceProvider extends ServiceProvider
{
Expand All @@ -34,6 +38,7 @@ public function boot()
$this->bootBladeComponents();
$this->bootCommands();
$this->bootCachedBreadcrumbs();
$this->bootThirdParty();
}

public function register()
Expand Down Expand Up @@ -121,4 +126,22 @@ protected function bootCachedBreadcrumbs(): self

return $this;
}

protected function bootThirdParty(): self
{
$config = $this->app->make(Repository::class);

$packages = $config->get('gretel.packages', []);

if (Arr::get($packages, 'inertiajs/inertia-laravel') && class_exists(Inertia::class)) {
Inertia::share('breadcrumbs', static function(Request $request) {
if ($route = $request->route()) {
return $route->breadcrumbs()->jsonSerialize();
}
return [];
});
}

return $this;
}
}
15 changes: 15 additions & 0 deletions tests/Mocks/Inertia.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Glhd\Gretel\Tests\Mocks;

class Inertia
{
public static array $shared = [];

public static function share($name, $value)
{
static::$shared[$name] = $value;
}
}

class_alias(Inertia::class, 'Inertia\\Inertia');
48 changes: 48 additions & 0 deletions tests/ThirdPartyPackagesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Glhd\Gretel\Tests;

use Closure;
use Glhd\Gretel\Tests\Mocks\Inertia;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Support\Facades\Route;

// We need to manually import this so that \Inertia\Inertia exists when the package boots
require_once __DIR__.'/Mocks/Inertia.php';

class ThirdPartyPackagesTest extends TestCase
{
public function test_it_registers_breadcrumbs_with_inertia(): void
{
Route::middleware(SubstituteBindings::class)->group(function() {
Route::get('/', fn() => 'OK')->name('home')->breadcrumb('Home');
Route::get('/users', fn() => 'OK')->name('users.index')->breadcrumb('Users', 'home');
Route::get('/users/create', fn() => 'OK')->name('users.create')->breadcrumb('Create User', '.index');
});

$this->get(route('users.create'))->assertOk();

$this->assertArrayHasKey('breadcrumbs', Inertia::$shared);
$this->assertInstanceOf(Closure::class, Inertia::$shared['breadcrumbs']);

$expected = [
[
'title' => 'Home',
'url' => route('home'),
'is_current_page' => false,
],
[
'title' => 'Users',
'url' => route('users.index'),
'is_current_page' => false,
],
[
'title' => 'Create User',
'url' => route('users.create'),
'is_current_page' => true,
],
];

$this->assertSame($expected, $this->app->call(Inertia::$shared['breadcrumbs']));
}
}

0 comments on commit c396e01

Please sign in to comment.