Skip to content

Commit

Permalink
Support null breadcrumb URLs (#15)
Browse files Browse the repository at this point in the history
* Add failing tests for `null` routes; define child/parent routes

* Update method signature to accept `null` URLs

* Update documentation

* Fix JSON syntax in README to remove red GitHub highlighting

* Remove leading backslash to match project code style

* Reword sentence

* Re-fix typo after rebase

* Adjust copy for pending version change

---------

Co-authored-by: Robert Boes <2871897+RobertBoes@users.noreply.github.com>
  • Loading branch information
shengslogar and RobertBoes authored Apr 26, 2024
1 parent ba9c478 commit 5e04c6f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 15 deletions.
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,22 @@ No matter which third party package you're using, this package will always share
```json
[
{
title: "Dashboard",
url: "http://localhost/dashboard",
"title": "Dashboard",
"url": "http://localhost/dashboard"
},
{
title: "Profile",
url: "http://localhost/dashboard/profile",
current: true,
"title": "Profile",
"url": "http://localhost/dashboard/profile",
"current": true
},
{
"title": "Breadcrumb without URL"
}
]
```

Note that due to package differences, URLs are always present when using `glhd/gretel`, but are otherwise optional.

An example to render your breadcrumbs in Vue 3 could look like the following:

```js
Expand All @@ -81,12 +86,13 @@ An example to render your breadcrumbs in Vue 3 could look like the following:
<ol>
<li v-for="page in breadcrumbs">
<div>
<span v-if="page ==='/'">/</span>
<span v-if="page === '/'">/</span>
<a
v-else
v-else-if="page.url"
:href="page.url"
:class="{ 'border-b border-blue-400': page.current }"
>{{ page.title }}</a>
<span v-else>{{ page.title }}</span>
</div>
</li>
</ol>
Expand Down
20 changes: 20 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ This document outlines breaking changes introduced in 0.x versions and major rel

We accept PRs to improve this guide.

## From 0.5.x to 0.6.0

### Breadcrumbs without a route

`null` breadcrumb URLs are now supported for `diglactic/laravel-breadcrumbs` and `tabuna/breadcrumbs` collectors.
Previously, defining a `null` URL would've thrown an exception, so this is technically a backwards-compatible change.
However, because this changes the array shape of outputted breadcrumbs, you may want to update your frontend components
to match. Here's an example TypeScript type to illustrate:

```diff
type Breadcrumb {
title: string;
- url: string;
+ url?: string;
current?: boolean;
};

type Breadcrumbs = Breadcrumb[];
```

## From 0.4.x to 0.5.x

### Upgrading dependencies
Expand Down
6 changes: 5 additions & 1 deletion src/Collectors/AbstractBreadcrumbCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ public function __construct()
}
}

protected function isCurrentUrl(Request $request, string $url): bool
protected function isCurrentUrl(Request $request, ?string $url): bool
{
if (is_null($url)) {
return false;
}

if (config('inertia-breadcrumbs.ignore_query', true)) {
return $request->url() === $url;
}
Expand Down
9 changes: 6 additions & 3 deletions tests/CollectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ public function it_throws_an_exception_when_required_class_does_not_exist()
public function it_creates_breadcrumb_collection_from_breadcrumbs()
{
$breadcrumbs = new BreadcrumbCollection([
new Breadcrumb('test', false),
new Breadcrumb('required', false),
new Breadcrumb('with-url', false, 'localhost'),
new Breadcrumb('with-null-url', false, null),
new Breadcrumb('with-data', false, 'localhost', ['foo' => 'bar']),
]);

$this->assertSame(1, $breadcrumbs->items()->count());
$this->assertSame(4, $breadcrumbs->items()->count());
}

#[Test]
public function it_throws_an_excpetion_with_invalid_breadcrumbs()
public function it_throws_an_exception_with_invalid_breadcrumbs()
{
$this->expectException(CannotCreateBreadcrumbException::class);
new BreadcrumbCollection([
Expand Down
12 changes: 10 additions & 2 deletions tests/DiglacticCollectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,20 @@ public function it_throws_an_exception_when_package_is_not_installed()
#[Test]
public function it_collects_diglactic_breadcrumbs()
{
DiglacticBreadcrumbs::for('profile.edit', function (DiglacticTrail $trail) {
DiglacticBreadcrumbs::for('profile', function (DiglacticTrail $trail) {
$trail->push('Profile', route('profile'));
});

DiglacticBreadcrumbs::for('profile.edit', function (DiglacticTrail $trail) {
$trail->parent('profile');
$trail->push('Edit profile', route('profile.edit'));
$trail->push('Crumb without link');
});

$request = RequestBuilder::create('profile.edit');
$crumbs = app(BreadcrumbCollectorContract::class)->forRequest($request);

$this->assertSame(2, $crumbs->items()->count());
$this->assertSame(3, $crumbs->items()->count());
$this->assertSame([
[
'title' => 'Profile',
Expand All @@ -103,6 +108,9 @@ public function it_collects_diglactic_breadcrumbs()
'url' => route('profile.edit'),
'current' => true,
],
[
'title' => 'Crumb without link',
],
], $crumbs->toArray());
}

Expand Down
12 changes: 10 additions & 2 deletions tests/TabunaCollectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,20 @@ public function it_throws_an_exception_when_package_is_not_installed()
#[Test]
public function it_collects_tabuna_breadcrumbs()
{
TabunaBreadcrumbs::for('profile.edit', function (TabunaTrail $trail) {
TabunaBreadcrumbs::for('profile', function (TabunaTrail $trail) {
$trail->push('Profile', route('profile'));
});

TabunaBreadcrumbs::for('profile.edit', function (TabunaTrail $trail) {
$trail->parent('profile');
$trail->push('Edit profile', route('profile.edit'));
$trail->push('Crumb without link');
});

$request = RequestBuilder::create('profile.edit');
$crumbs = app(BreadcrumbCollectorContract::class)->forRequest($request);

$this->assertSame(2, $crumbs->items()->count());
$this->assertSame(3, $crumbs->items()->count());
$this->assertSame([
[
'title' => 'Profile',
Expand All @@ -84,6 +89,9 @@ public function it_collects_tabuna_breadcrumbs()
'url' => route('profile.edit'),
'current' => true,
],
[
'title' => 'Crumb without link',
],
], $crumbs->toArray());
}

Expand Down

0 comments on commit 5e04c6f

Please sign in to comment.