The goal of this update is to replace the static way of creating routes with a more dynamic implementation. The result is a cleaner approach that is easier to set up and review at a glance.

RoutesDelegator.php is used to configure the routes in Dotkernel applications. Routing allows web applications to respond to user requests by executing the correct code based on URL paths. The dynamic aspect discussed in this article moves the relevant items for each route into the local.php file. The RoutesDelegator then reads the route configuration and generates the routes.

This is the first in a series of articles for switching from controllers to handlers that are PSR-15 compliant. It’s aimed at static pages alone, so any other method like post, put or delete will return a 405 status code.

The old way of doing things

In the past, declaring routes had a more static, hard-coded approach. All our modules have a RoutesDelegator.php file in the src folder for each module. Each route would have an entry like the one below:

$app->get('/page[/{action}]', [GetPageViewHandler::class], 'page');

This route would be used for urls like /page/about or /page/who-we-are that we will reference later.

These are the required items:

  • A method, in this case get which is aimed at static pages.
  • A path used to direct the execution to a handler, in this case /page[/{action}] which also uses the optional parameter action.
  • A handler to be executed, like GetPageViewHandler which is designed to display static pages out of the box, but can be expanded as needed.
  • A unique route name, like page which can be referenced to generate redirects or set up authorization.

In a live application the route list can quickly grow to many more entries, each with its own logic:

  • Product list
  • Product details
  • Checkout
  • Contact us
  • Reports
  • Order History
  • Blog

These items can be grouped into modules, meaning you have to dig into multiple RoutesDelegators when a routing error occurs.

The new approach

The update centralizes the route configuration in the config/autoload/local.php file. Here is how the routing looks out of the box:

'routes'      => [
    'page' => [
        'about'      => 'about',
        'who-we-are' => 'who-we-are',
    ],
],

This supports the urls /page/about and /page/who-we-are.

Let’s list the components under the routes array:

  • page is the module name.
  • The key about is used to build the page’s path.
  • The value about is the template file.

In this setup, the RoutesDelegator file doesn’t need to be touched most of the time. This is how it generates the routes for each page:

$routes = $container->get('config')['routes'] ?? [];
foreach ($routes as $prefix => $moduleRoutes) {
    foreach ($moduleRoutes as $routeUri => $templateName) {
    $app->get(
        sprintf('/%s/%s', $prefix, $routeUri),
        GetPageViewHandler::class,
        sprintf('%s::%s', $prefix, $templateName)
    );
    }
}

Each item under routes array for each module will have its own entry. The result is you have a get for the about page and another for the who-we-are page.

Advanced configuration

You have the same versatility as before for route configuration. Below we explore some scenarios that showcase the control you still have over the routing.

The template file is taken from the path, but you can still change that in the handler based on your requirements. Replace $template = $request->getAttribute(RouteResult::class)->getMatchedRouteName(); with a template of your choosing, like $template = 'my-template';

Say you want to change the url from /page/about, to /about for SEO purposes. All you have to do is remove the $moduleName parameter from sprintf('/%s/%s', $moduleName, $routeUri), making it sprintf('/%s', $routeUri),. Take care not to break other routes, though!

If you need to change the url parameter, you can do that in the local.php file. Edit 'about' => 'about', into 'about-us' => 'about',. This changes the original url to /page/about-us, but uses the same about template as before.

Do you need a dynamic parameter? Edit the route entry from 'about' => 'about', to 'about/{id}' => 'about',. This expands the matched url to support something like /page/about/us, /page/about/company, /page/about/123 which will allow you to customize each url with different content in the handler. All you need is to use $request->getAttribute('id') to tell what page you are on.

Additional resources

Dotkernel Light

Dotkernel Light Routing How to

FastRoute


Looking for PHP, Laminas or Mezzio Support?

As part of the Laminas Commercial Vendor Program, Apidemia offers expert technical support and services for:

  • Migration from Laminas MVC to Mezzio or Dotkernel Headless Platform.
  • Migration from legacy Laminas API Tools (formerly Apigility) to Dotkernel API
  • Mezzio and Laminas Consulting and Technical Audit
  • Modernising Legacy Applications
  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>