Hook page.create:before, how to edit user input?

When creating a page in a pages section I’d like to intercept user input and change e.g. slug to something else.

How would I do that with a page.create:before hook? What would I return?

'page.create:before' => function ($parent, $input) {
      $input['slug'] = 'randomslug';
      // return ...?
}

When I change the slug in the page.create:after hook, the panel redirects to the wrong url (the old slug).

'page.create:after' => function ($page) {
    $page->changeSlug('randomslug');
}
1 Like

I’m not sure, but I don’t think this can be achieved with a before hook. I see two options:

  • A page.create:after hook that changes the slug and redirects to the new URL
  • A custom pages section with its own page create logic
1 Like

hm…I am not able to change the page.id that is sent back to the panel. All Objects are protected…so an own redirect seems impossible.

A custom pages section is an option I want to consider as last resort.

The only way I found was to intercept the request before it was processed by Kirby. So back to the route:before hook.

'route:before' => function ($route, $path, $method) {
    if ($method === "POST") {
        if (preg_match('/pages\/.*\/children$/', $path) === 1) {
            if($request = json_decode(file_get_contents('php://input'), true)) {
                $request['slug'] = "mynewslug";
                $_POST = $request;
            }
        }
    }
}
1 Like

You could also overwrite the create() method of the parent page in a custom page model.


class ParentPage extends Page
{
    /**
     * Creates and stores a new page
     *
     * @param array $props
     * @return Page
     */
    public static function create(array $props): Page
    {
        $props['slug'] = 'mynewslug';
        
        return parent::create($props);
    }
}

11 Likes

A very elegant solution!

Hi,
i’d like to use this for overwriting the url with a random string for newly added content.
So i added this code to site/model/event.php and changed the class name to EventPage. I also added a page blueprint (event.yml) with custom fields to site/blueprints/pages. After clicking “Create draft” in the panel the new create function is not getting called and so the new content has still the same default url. Do you have any further information what i’m doing wrong?

Thanks

@daw Hey, Welcome to the Kirby forum.

Is the Event page your parent page?

Hi @texnixe, thanks for your fast reply. I’m new to Kirby so i’m not really sure about that. But i used the Events sample in the docs. It’s almost the same, i only added some new fields.
https://getkirby.com/docs/reference/panel/samples/events

If your parent is the page with the events.yml blueprint like in the example, your model has to match that page, e.g. you would have to create an events.php model with the method above.

1 Like

Hi, I’d like to edit @lukaskleinschmidt solution so that the new slug will be “myTitle + thisYear.”

But I can’t get the filed title() from modal. Where am I making mistake? Thank you for your help.

Not tested but it should probably look something like this.

class ParentPage extends Page
{
    /**
     * Creates and stores a new page
     *
     * @param array $props
     * @return Page
     */
    public static function create(array $props): Page
    {
        $props['slug'] = $props['content']['title'] . '-' . date('Y');
        
        return parent::create($props);
    }
}

Note:

Since Kirby 3.4 you need to overwrite the create method on the actual page model that is going to be created. Not the parent model!

2 Likes

Thank you for the quick reply.

But for your solution, the panel writes the error: “Undefined index: title”.

I’m thinking, can modal give this value?

Just checked and it has to be $props['content']['title'] instead of $props['title']. I updated the answer above.

Great! Now it really works. @lukaskleinschmidt thank you very much for your help.

Hi everyone,

I updated my site from Kirby 3.3.6 to the new version 3.4.0 and then this Custom page model from @lukaskleinschmidt stopped working.

I think it could be related to a change of Hooks or new $props arguments in the new Kirby version. But I can’t fix this code.

Can you advise me where I am making a mistake? Thank you advance.

Nope, that code should still work. It has nothing to do with the hooks. Do you get an error or just not the desired result? Are you using this in conjunction with a plugin?

This doesn’t print any error. Only the command is not executed. When I go back to version 3.3.6, then the code works again. The file is only in the site/models folder. S plugins it isn’t connect.

Just had a look at this. It is related to this commit. So instead of overwriting the create method on the parent model you now have to do this on the actual page model that is going to be created.

@texnixe could you please add a info to my post above like:

Since Kirby 3.4 you need to overwrite the create method on the actual page model that is going to be created. Not the parent model!

Ah, ok, that explains why it works in my environment.