404 notFoundHandler - different template for routes

I’m wondering if there is any way to run other 404 notFoundHandler or different twig template depending on route.

I have 3 routing groups:
Website - '/'
Website admin panel - '/admin’
Api - ‘/api’

I have working notFoundHandler for 404 but i want to use other notFoundHandler or render different template depending on where 404 was returned. For example:

/admin/badUrl - should run adminNotFoundHandler or at least render templates/admin/404.twig
/api/badUrl - should run apiNotFoundHandler without rendering template - just 404
/anyOtherBadUrl - should run websiteNotFoundHandler or at least render templates/website/404.twig

At this point im thinking if it would be a good idea to actually create 3 app entrypoints with .htaccess and just split each app specific classes, dependencies, settings etc. which would resolve this problem.

I have seen a workaround there: Handling multiple 404’s? but it doesn’t really feel right to change handler behaviour depending on URI path.

You can add an application middleware to replace ‘notFoundHandler’ in the container:

$container = [
    'admin.notFoundHandler' => function($container) { /* ... */ },
    'api.notFoundHandler' => function($container) { /* ... */ }
];

$app = new Slim\App($container);

$app->add(function($request, $response, $next) use ($app) {
    // change notFoundHandler based on the request path match
    $container = $app->getContainer();
    $path = $request->getUri()->getPath();

    if (preg_match('#/admin(/.*)?$#', $path)) {
        $container['notFoundHandler'] = function ($container) { 
            return $container->get('admin.notFoundHandler'); 
        };
    } elseif (preg_match('#/api(/.*)?$#', $path)) {
        $container['notFoundHandler'] = function ($container) { 
            return $container->get('api.notFoundHandler'); 
        }; 
    }

    return $next($request, $response);
});

$app->run();
1 Like