glhd / gretel

Laravel breadcrumbs right out of a fairy tale
MIT License
243 stars 16 forks source link

Easily add breadcrumbs to routes of packages without overriding them #8

Closed ThaDaVos closed 2 years ago

ThaDaVos commented 2 years ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] Current I am using Laravel Jetstream in my application, this package registers a lot of default routes - currently I haven't foùnd an easy way, except overriding the full route, to add breadcrumbs to these... Describe the solution you'd like A clear and concise description of what you want to happen.

An easy way to add breadcrumbs to routes not in your control without the need of overiding them, something like:

Gretel::breadcrumb('{ROUTE_NAME}', ....{NORMAL GRETEL PARAMS});
// OR
Gretel::breadcrumb('{ROUTE_URI}', ....{NORMAL GRETEL PARAMS});

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Overriding the full route to add the breadcrumb

Additional context Add any other context or screenshots about the feature request here.

ThaDaVos commented 2 years ago

Just like this one supports: https://github.com/diglactic/laravel-breadcrumbs

ThaDaVos commented 2 years ago

I've done it this way for now:

Added new ServiceProvider to the end of the providers list in config/app.php with following content:

<?php

namespace App\Providers;

use Illuminate\Routing\Router;
use Glhd\Gretel\Macros as Gretel;
use Glhd\Gretel\Registry;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as FacadesRoute;
use Illuminate\Support\ServiceProvider;

class BreadcrumbsServiceProvider extends ServiceProvider
{
    /**
     * @var Registry
     */
    protected Registry $registry;

    /**
     * Create a new service provider instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct($app)
    {
        parent::__construct($app);

        $this->registry = $app->make(Registry::class);
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->booted(
            fn () => $this->registerBreadcrumbs()
        );
    }

    public function breadcrumb($name, $title = null, $parent = null, $relation = null): Route|null
    {
        $route = FacadesRoute::getRoutes()->getByName($name);

        if (is_null($route)) {
            return null;
        }

        return Gretel::breadcrumb($this->registry, $route, $title, $parent, $relation);
    }

    /**
     * Load the routes/breadcrumbs.php file (if it exists) which registers available breadcrumbs.
     *
     * This method can be overridden in a child class. It is called by the boot() method, which Laravel calls
     * automatically when bootstrapping the application.
     *
     * @return void
     */
    public function registerBreadcrumbs(): void
    {
        require base_path('routes/breadcrumbs.php');
    }
}

And then I define them in routes/breadcrumbs.php like this:

<?php

$this->breadcrumb('register', 'Register');
inxilpro commented 2 years ago

Yeah, that makes a lot of sense. It should be fairly easy to add something like:

Gretel::custom(
  route: 'teams.show',
  title: fn(Team $team) => $team->name,
  parent: 'profile.show',
  parameters: ['team'],
);

The only thing that kinda sucks is that Gretel needs to know the route's parameter names in advance, so you'd have to pass them in. I'm trying to think if there's a way to get around that…

inxilpro commented 2 years ago

@ThaDaVos I just pushed a feature to @glhd/gretel:dev-main that should do the trick. You can just call Gretel::breadcrumb() with the same arguments as normal, but with the route name as an extra first argument.

Gretel::breadcrumb(
  route: 'teams.show',
  title: fn(Team $team) => $team->name,
  parent: 'profile.show',
);

If you have a chance to try it and confirm it works for your use-case, that'd be great. I'll do some testing later this week and release it.

ThaDaVos commented 2 years ago

Great! I'll take a look when I have the time - I have changed my local implementation though so I was able to auto-generate a routes/breadcrumbs.php file (I was a bit lazy)

inxilpro commented 2 years ago

This is available in 1.6.0!