How to: basic routing

Hi,

I would like some help with routing. Let’s say that I have the following site structure:

Services

  • Wedding Photography
  • Family Photography

The URL of the service page is domainname.com/services/wedding-photography and domainname.com/services/family-photography

What exactly do I have to put in my config file in order to make all my service pages url’s appear without “service” in the url? Example: domainname.com/wedding-photography

From what i can find in the docs, i can’t get any further then this:

return [
  'routes' => [
    [
      'pattern' => '/services/(:all)',
      'action'  => function (string $path) {
        // react to requests
      }
    ]
  ]
];

You need two routes:

  1. The first one redirects request to the services subpages to a route without the services part
  2. The second route then returns the actual subpage if one of your wedding Urls is called.

This should work:

'routes' => [
    [
        'pattern' => '(:any)',
        'action'  => function($uid) {

            $page = page($uid);

            if(!$page) $page = page('services/' . $uid);
            if(!$page) $page = site()->errorPage();

             return $page;

        }
    ],
    [
        'pattern' => 'services/(:any)',
        'action'  => function($uid) {
            go($uid);
        }
    ]
]

Thank you! It works perfectly.

I think it would be nice to include a routing example in the Kirby starterkit.

Hm, I don’t think the Starterkit is the right place for that. But we had an example like the above in the Kirby 2 docs and it would make sense to also put it into the Kirby 3 docs.

Hi,
I had a similar problem and the solution worked great. But it breaks my multi language site. I get an error now when I go to the English homepage (domain.de/en).

Any ideas how to fix that?

Routes have a language property, see the docs for routing.

Thanks for this explanation @texnixe. Why does the services/(:any) route come after the (:any) route? Seems to me like the order should be reversed: first looking for a subpage, then returning subpage data if it exists.

@lukehatfield Not sure if the order is really important in this particular case (but order of routes can be important).

The second route is basically only a fallback, it redirects to the first route if it is called for any reason (this would basically only happen if someone enters the address manually).

Because in our code, we would of course not use the real URL, but a page model or method that outputs the final URL, i.e. the one we cover in the first route.

1 Like