Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel two 404 styles

Tags:

php

laravel

I have a main site and an admin control panel.

I want to have different 404 pages for each version.

How should I do this? I currently have the following code in my app/Exceptions/Handles.php file:

/**
    * Render an exception into an HTTP response.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Exception  $exception
    * @return \Illuminate\Http\Response
    */
public function render($request, Exception $exception)
{
    if($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
    {
        $view = $request->is('admin/*') ? 'acp.errors.404' : 'errors.404' ;

        return response()->view($view, [], 404);
    }
    return parent::render($request, $exception);
}

But I use the package spatie/laravel-permission and get the following error;

Trying to get property 'role' of non-object (View: F:\Development\RPR\site\resources\views\layouts\acp.blade.php) (View: F:\Development\RPR\site\resources\views\layouts\acp.blade.php)

I use in acp.blade.php auth()->user()->role, to get the user role, which just works fine without any exception. How should I fix this?

like image 771
Robin Avatar asked Nov 06 '22 20:11

Robin


1 Answers

Here are two ways to accomplish different 404 views depending on the route. Both will allow you to have these error pages:

/resources/views/acp/errors/404.blade.php
/resources/views/errors/404.blade.php

The directories will be checked in order until a view is found, which means you can selectively add custom error views and fall through to the default when none exist. If the route did not match, then it will not look for a custom error page.

Option 1

Override registerErrorViewPaths() inside app/Exceptions/Handler.php:

/**
 * Register the error template hint paths.
 *
 * @return void
 */
protected function registerErrorViewPaths()
{
    parent::registerErrorViewPaths();

    if (request()->is('admin/*')) {
        View::prependNamespace(
            'errors',
            realpath(base_path('resources/views/acp/errors'))
        );
    }
}

Option 2

Create a ViewServiceProvider:

php artisan make:provider ViewServiceProvider

Register your provider in config/app.php:

'providers' => [
    // ...

    App\Providers\ViewServiceProvider::class,
],

Edit the boot method of your provider:

/**
 * Bootstrap services.
 *
 * @return void
 */
public function boot()
{
    if (request()->is('admin/*')) {
        View::prependNamespace(
            'errors',
            realpath(base_path('resources/views/acp/errors'))
        );
    }
}

For the second part of the question, auth()->user() is only available when the session middleware has run. If the 404 was caused by the route not existing, then the request does not go through the web middleware and unfortunately sessions and auth information will not be available. However, if the 404 was caused by a ModelNotFoundException triggered inside a controller, then the web middleware probably did run and you can access the user.

Inside your error view you have to check if the user is signed in:

@guest
    <p>Hello, guest</p>
@else
    <p>Hello, {{ auth()->user()->name }}</p>
@endguest

If this is not good enough for your use case, then you might want to try Route::fallback(), which allows you to define a controller for serving 404 pages and does run web middleware.

like image 53
Travis Britz Avatar answered Nov 14 '22 22:11

Travis Britz