Routes - Prevent nesting from hell?

In some routes I have it looks like a nightmare:

array(
	'pattern' => '(:any)/(:any)',
	'action'  => function($part1, $part2) {
array(
	'pattern' => '(:any)/(:any)/(:any)',
	'action'  => function($part1, $part2, $part3) {
array(
	'pattern' => '(:any)/(:any)/(:any)/(:any)',
	'action'  => function($part1, $part2, $part3, $part4) {

It’s a nightmare. A few questions to that.

  • Is it possible to have one pattern that matches anything across the slashes?
  • In the function, is it possible to have the arguments as one array instead of strings? The it would be easier to foreach them.

What I really want is one route that matches anything and that carries the page object.

Image viewer

I’m building an image viewer for a site where it should do one thing if it’s an image and another thing if it’s not. It looks for a dot to determine if it’s an image or not.

my/very/long/url/with/an/image/at/the/end/my-image.png
my/very/long/url/with/an/image/at/the/end/something-else
my/image.jpg
my/something-shorter

I know I could create own functions to “generate” the routes, but that makes it more abstract.

Sure. Please note that this will really match everything.

array(
	'pattern' => '(:all)',
	'action'  => function($uri) {
		$parts = explode('/', $uri);

Wouldn’t it make more sense then to use a regular expression? Don’t know if that get’s you the page object, though.

For me it does not match anything at all. In the config file I have this:

c::set('routes', array(
	array(
		'pattern' => '(:all)',
		'action' => function($uri) {
			echo $uri;
			die;
		}
	)
));

It loads the page as if the route was not there. No match.

I have no other routes or plugins installed except for the Patterns plugin.

UPDATE

This worked:

c::set('routes', array(
	array(
		'pattern' => '(.*)',
		'action' => function($uri) {
			echo $uri;
			die;
		}
	)
));

Oh, sorry. Seems like (:all) only works when there’s something else in the URL.

I replaced the pattern with (.+) and it worked. It will also match existing pages, so you need to handle these cases as well.

Thanks! I also found a regex that worked, in the updated post above. I’m not a regex pro so I don’t know what to prefer of (.*) or (.+)?

Thanks @texnixe for your push in the right direction.

UPDATE

I found it myself which probably mean I should use (.+) to not match some empty string.

Yes, (.+) is probably better, but you can’t normally match empty strings (a leading slash is always in the URL).

Actually the pattern (:all) is just a shorthand for (.*) in Kirby, but that doesn’t seem to work if it is alone in the pattern.

Is it a bug? Add issue?

I will look into it later and send a PR if I find the issue.

It’s really strange and I haven’t found out why it is happening. See this issue on GitHub.