How to redirect after slug changed in 'page.update:after' hook?

My question is similar to this one Change Slug in 'page.create:after' Hook

The suggested solution does work in case of create() within a Custom PageModel but doesn’t seem transferable to the update() method (I got the slug to change but it didn’t redirect to the new slug either).

So now, as @texnixe suggested here: Hook page.create:before, how to edit user input? - #2 by texnixe

I try to redirect to the new URL but I couldn’t figure out how to do this from within the hook…
I tried to use go($page->panelUrl()) and also $page->panelUrl()->visit() without luck.

Thanks in advance for any advice :slight_smile:

I’m now trying to update the slug when the status changes (page gets published) in the page.changeStatus hook… but It seems that whenever I use

$page->changeSlug('to-new-slug');

programatically while being on that $page in the Panel, no redirect happens and the Error: Cannot find page/old-slug shows up. I then have to go back to the parent page and refresh the Panel before I can visit the (correctly updated) child page again.

Changing the slug itself works, especially when the status gets changed from the parent’s pages section no problem occurs at all.

Kirby seems to use the same changeSlug() function but it redirects to the new slug somehow.
Unfortunately, I wasn’t able to figure out how this redirect works yet, although I searched Kirby’s source-code :man_shrugging:

Any ideas?

This is where the redirect happens: https://github.com/getkirby/kirby/blob/develop/panel/src/components/Dialogs/PageUrlDialog.vue#L102-L108

However, I do not think that there is any way at the moment to make this happen from a hook.

One idea: Are you currently using the page.changeStatus:after hook? I’m trying to wrap my mind around it and it might work if you use the :before one.

Thanks a lot @distantnative for looking into this :slight_smile:

So the redirecting is completely handled in vue and is never invoked by hooks (PHP)?! :face_with_monocle:

Does the vue-part of Kirby know about the execution of hooks? If so, maybe Kirby could take care of such a redirect on changeSlug() whenever it’s invoked from the changing page in the Panel?

Yes, I’m using the page.changeStatus:after hook like follows

'page.changeStatus:after' => function ($newPage, $oldPage) {
    if ($newPage->intendedTemplate() == 'termin') {
        // Event got published (date and city are set)
        if ($newPage->isListed()) {
            // create unique Event-ID from date and city in consistent format
            $slug = $newPage->prefix() . $newPage->start_date()->toDate('%y%m%d') . mb_substr($newPage->city(), 0, 2, 'utf-8'));
            $newPage->changeSlug($slug); // prepending 'return' doesn't seem to make a difference
            // also appending '->save()' like I saw in Kirby's source doesn't seem to.
        }
    }
}

I tried to do this in the page.changeStatus:before hook like you suggested.

Unfortunately, the slug change prevents/blocks the status change (slug change works but shows the same error when on page and the status change doesn’t happen even if triggered from the parent pages section).

BTW: I just noticed that even without any hooks involved, the console logs an error when changing the slug of any page:

Object {
  status: "error",
  exception: "Exception",
  message: "No route found for path: \"null\" and request method: \"GET\"",
  file: "kirby/src/Http/Router.php",
  line: 120,
  code: 404
} app.js:1:236022

Should I file an issue?
Looks like Kirby always throws this Exception when the find() function get’s called:

Yes please!

Done: [Cms] Changing the slug of a page in the Panel always throws an Exception · Issue #1541 · getkirby/kirby · GitHub :wink:

I’ve just gone the same route as REH: I want to automatically update my page title and slug based on a field. I’ve searched the forums and haven’t found a working solution. Is there currently no way to achieve this?

1 Like

@bastianallgeier? @distantnative? Any updates?

Not really, sorry. Currently there is no real way of triggering anything in the Panel from inside a hook other than errors (by throwing an Exception).

It’s tricky as the Panel is mostly its own javascript app, communicating via the API - so back channels have to be defined individually (what response could an API request provide).

Is there any news on this?

I just tried this with 3.5.7.1 and I can’t get in to work to redirect to the new slug or the parent.

I figured a way to handle slug automatic rename and redirect through this draft plugin that I made a post about. If anybody is ever interested to download the code and modify it to their needs, feel free to do it!

I think it would be possible to modify it to just handle the redirect if you need.