Jump to content

PW 3.0.173 – Core updates, new hook type


ryan

Recommended Posts

I'm getting a look at this thread linked from the PW Weekly, where it looks like this topic has been discussed. BitPoet has an example where named arguments are in the format like "{user}" (if I understood it correctly) and I really like that. It would provide for an option to have named arguments without having to specify what would be in it... just "any valid PW page name characters". That sounds useful. I'll add support for it, in addition to the named arguments support mentioned in the blog post. We can support that without interfering with other regular expression features by having it convert that to a PCRE capture group. 

  • Like 10
Link to comment
Share on other sites

Love the new URL hooks!

The post doesn't mention what happens when a hooked URL or regex matches an existing page URL, but on testing it looks like the page URL takes precedence. That makes sense.

In the blog post there are examples where trailing slashes are present and absent, and tests seem to show that the hooked URLs work regardless of whether a trailing slash is present or absent in the requested URL. But what if you want to enforce a trailing slash or no trailing slash and redirect accordingly as per real page URLs?

  • Like 5
Link to comment
Share on other sites

Oh my, this is excellent!

A first use case I thought of was archives (eg. blogs) filtered by date: YYYY/MM/DD

/**
 * This example merely displays back the selected date as a string, but it could be used to show date-based archives.
 * The following URLs are valid:
 * /YYYY
 * /YYYY/MM
 * /YYYY/MM/DD
 */

// Build basic date regex to eliminate very silly things (e.g. 2021/15/92)
$dateRegexY = '(year:\d{4})'; // any four digits (could be narrowed, e.g. '(19|20)\d{2}'
$dateRegexM = '(month:(0[1-9]|1[0-2]))'; // 01-09 or 10-12
$dateRegexD = '(day:(0[1-9]|[1-2][0-9]|3[0-1]))'; // 01-09, 10-29, 30-31 (will need further validation!)

// Put it together
$dateRegex = '/' . $dateRegexY . '(/' . $dateRegexM . '(/' . $dateRegexD . ')?)?';

$wire->addHook($dateRegex, function($event) {
	$date = $event->year
	. ($event->month ? '/' . $event->month : '')
	. ($event->day ? '/' . $event->day : '');

	return $date;
});

The possibilities are endless.

Edited by LMD
Forgot October existed; other fixes
  • Like 5
Link to comment
Share on other sites

Another showcase ?

$this->addHook('/rockgrid2/(.*)', function($event) {
  $name = trim($event->arguments(1),"/");
  $grid = $this->getGrid($name);
  if(!$grid) throw new Wire404Exception("Grid not found");
  if($event->config->ajax) $grid->json(); // send json and die()
  return $grid->debug();
});

When requested via AJAX you get gzipped json (as source for a tabulator grid), when requested in the browser you get a sortable+filterable grid of your data ? 

aSE3hfI.png

And tracy is always waiting for bd() calls for quick and easy debugging ? 

  • Like 8
Link to comment
Share on other sites

@ryan great work, I love this! This can totally form part of a great API endpoint generator. Or auto allowing Ajax endpoints for getting resources. 

Is it possible to get the whole request URL in the hook handler? Incase you want to handle any number of sub routes? Or do you have to explicitly name each path segment? 

(Oh I guess the regex option enables this as per your JSON example. )

  • Like 2
Link to comment
Share on other sites

Quote

The post doesn't mention what happens when a hooked URL or regex matches an existing page URL, but on testing it looks like the page URL takes precedence. That makes sense.

@Robin S That's correct, an existing page has precedence. I'd like to make it so you can optionally override that too, but still working to identify the most efficient way. I'm trying to avoid a solution that adds the overhead of checking hooks and regular expressions for every request before identifying the page. Currently it only does that if the request doesn't end up matching a page, which adds no overhead to page rendering requests. Once the technical details are worked out, likely the solution will involve using an $wire->addHookBefore('/path/', ...) (rather than just addHook) which will receive a matched page (if there is one) and then it can decide whether to let it proceed as-is, change the Page object, or do something else. 

Quote

In the blog post there are examples where trailing slashes are present and absent, and tests seem to show that the hooked URLs work regardless of whether a trailing slash is present or absent in the requested URL. But what if you want to enforce a trailing slash or no trailing slash and redirect accordingly as per real page URLs?

That's also a technical still to work out. We could easily enforce trailing vs non-trailing slash but didn't want to do it without someone dictating that's what they want. Otherwise someone could very easily end up having every request getting 301'd without realizing it. So seemed safest just to allow either for the moment. I do plan to add a way to let you dictate what's required so that it can perform necessary redirects for you. I'm currently thinking that if the match pattern ends with a slash, it'll enforce the slash; if it doesn't, it'll enforce no-slash; and if it ends with a /? it'll allow for either. 

Quote

Quick question: will ProCache be able to cache (the result from) these URL hooks?

@eelkenet It doesn't at present since the feature was just added, but I do think it will be possible for ProCache to cache them. I've already started looking into it here. 

Quote

Is it possible to get the whole request URL in the hook handler? Incase you want to handle any number of sub routes? Or do you have to explicitly name each path segment? 

@StanLindsey The entire matched URL is always in $event->arguments(0). If it would be helpful I can also add a named argument to it, like 'url' or something, so you could do $event->arguments('url'); or just $event->url 

 

  • Like 6
  • Thanks 1
Link to comment
Share on other sites

On 3/6/2021 at 1:44 PM, dotnetic said:

ProcessJumplinks could be modified to use this. Don't know if @Mike Rockett is still working on v2?

JL2 uses FastRoute to do what's being done here, although it obviously needs to hook into the 404 process in order to work. The reason I picked FastRoute was because, at the time, I simply didn't like the approach in current v1, and wanted something a little more robust, feature reach, and fast. JL2 could use this new feature (which is a great addition to PW), though some additional work would need to be done to make the URIs transform to the regex approach being used here, which is quite different.

That aside, I'm afraid JL2 on hold, once again. Simply don't have the time to take it on right now, and doubtful that I will any time soon. In all honesty, I would be much happier if someone were to take the project over and give it new life. It's been in the pipeline for a long time now, and it's really come down to me making promises I uninentionally couldn't keep, much as I wanted to be able to. So, if anyone is able and willing to take it over, please feel free to pop me a DM.

  • Like 4
Link to comment
Share on other sites

13 hours ago, maxf5 said:

Since the update (30173) pages with active pagination are throwing a 404.

Anybody also have this issue?

I can confirm this issue with the latest dev at time of posting (commit 6146ba4eb1fa3650a43c789a98026d7af4b5e317)

  • Thanks 2
Link to comment
Share on other sites

  • 3 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...