Get resource from url within custom route

I am at a position where I need a value from a resource template (either page, file, image, video etc.).
Based on that value I either need to return that resource, or redirect (to a login page, noting-found paget etc.).

I could simply register a hook for that (rout:after) and handle it from there, but the problem is that I really want this to be compatible with other plugins as well. Meaning either I need this hook to be fired first (no matter what!), or I need to manually query the url inside the route instance (without creating an infinite loop of course).

So how would one go about getting the resource from an url as it would have been if one puts it into the browsers-search bar?

I’m not quite sure I understand what you mean, what is a resource template?

Do you mean to access a file from the content folder like http://kirby.test/content/1_photography/1_trees/cheesy-autumn.jpg? And then either show this file or not based on conditions?

What I mean is that an url might refer to a ‘page’, ‘virtula page’, ‘image’, ‘video’ etc. most can have their own template/bleuprint. So based on some complicated conditions I either want to redirect, modify or block access to that page/file/resource.

If the given path is simply a location, things wouldn’t be so complicated. But since custom routes (and hooks) may be involved I don’t want to break that mechanism. In short it would be best if I could ‘fit’ code between the actual router and the route:after hook. As I might still redirect based on the conditions (after which the rest of the hooks still may apply).

so my thinking was:

  • option1: have a custom route installed, but use the default system to obtain the page/file/resource for the given path so I can access its properties etc. and handle it from there;
  • option2: have a route:after hook, but make sure it is fired before all the others to not mess up the other hooks.

The important part is, that I don’t want to interupt/mess up other plugins’ route mechanics (as I don’t know at forehand which plugins will be installed besides the one I am currently developing).

For some extra information: url-parameters are involved in the process, so I would prefer if this could be done within a router rather than a hook, so I don’t have to ‘reparse’ the given path

Hm, you could use a catch-all route (if necessary), check your conditions, redirect to error or login if condition is met, otherwise $this->next().

:smile: that was the idea indeed. But how do I get the ‘would be’ resource from the given parameters? (so I can query the result Object) The this->next() statement doesn’t return anything.

No, $this->next() just calls the next available route if the condition is not met.

Well, if you use a pattern (:all) you can use this inside your route to determine the resource. Or you use several routes depending on resource type, so that you don’t have to use too many conditions.

Note that as far as I know you cannot intercept the media route, but I haven’t tested this in a while.

I think we misinterpret the term resource here. I use that term for the ‘route-result Object’, while I suspect you refer to the route-function-parameter $path?

I need the Object to check parameters etc.

Well, but there is no way to magically detect the returned object from the route pattern ( = path), so you would have to check if that route returns a page or anything else.

And how is that done?

I mean you can use:

new Router(kirby()->routes())->call(/* arguments here */);

Or even

kirby()->router()->call(/* arguments here */);

But that will create an infinite loop, since the route I call this from is also included into the router.

Unfortunately I dont see a way to filter those routes, as I cannot seem to find a way to identify my own route (as one only declares a callback function, not the actual route object).

For example, you would check if the path is a page with

if ($page = page($all) ) {
  // do stuff
}

where $all contains the pattern .

You can get the route object with $this, but this won’t help you, because it doesn’t contain what the route returns, but the route object with properties like pattern, arguments etc.

Yep, that would work for regular path’s (where the url/path is the same as the directory layout). But it excludes custom route’s unfortunately. Is there some way to make a route identifiable? Because than it is solvable with the above snippit.

For custom routes, you should handle your logic right there. To prevent code duplication, you can outsource the logic into a function.

It may be that I do not own those custom route’s.

I am developing a plugin to be used with other site-themes and kirby-plugins.

So this question is purely meant to find a way which has the highest change of being compatible with any plugin/site-theme.