Syncing date field with page slug

In my website I can have several posts with the exact same title, so I’ve been using a date field to differentiate them in the slug, so I don’t get the error that the slug already exists.

I do this from the page creation modal:

create:
  slug: "{{ page.title }}-{{ page.date.toDate('Y-m-d') }}"
  fields: date

And my date field:

      date:
        type: date
        default: now
        display: DD/MM/YYYY

The issue is that if the date gets updated afterwards to use a different value (from the past, for example) the slug remains the same than when the page was created.

Is there any way I could sync the date field and the slug automatically if I change the date value?

Ultimately, I would even prefer that the slug and the folder of this page were exactly the same. When using this, the page folder does indeed update to reflect the change, unlike the slug:

num: '{{ page.date.toDate("Ymd") }}'

I have been reading the documentation and couldn’t find anything in this regard.

The only way to achieve this would be via a page.update:after hook that checks if the date has changed and then updates the slug.

Thank you. I’m new to hooks, and adding any hook in my config file such as:

<?php

return [
    'hooks' => [
        'page.update:after' => function ($page) {
            // do something
        }
    ]
];

Will trigger the following error when creating a new page (that uses “create” in the blueprint):

foreach() argument must be of type array|object, string given

Is there anything else that I should take into account / modify on my page blueprint?

Please see the hooks documentation, the parameter names must be $newPage, $oldPage: page.update:after | Kirby CMS

I’m sorry about this. For some reason I pasted the wrong code above. I did try with the example from the documentation, and got the same error message.

This is how my whole config.php looks like:

<?php

return [
    'hooks' => [
        'page.update:after' => function (Kirby\Cms\Page $newPage, Kirby\Cms\Page $oldPage) {
            // your code goes here
        }
    ]
];

Do you have any advice to sort this out please?

The fields property expects an array, so must be

fields:
  - date

Thank you; and I’m sorry for not seeing this. I created a hook that looks like this:

<?php

return [
    'hooks' => [
        'page.update:after' => function (Kirby\Cms\Page $newPage, Kirby\Cms\Page $oldPage) {
            
            if ($newPage->date()->toDate('Y-m-d') !== $oldPage->date()->toDate('Y-m-d')) {
                
                $newSlug = $newPage->date()->toDate('Y-m-d');
                $newPage = $newPage->changeSlug($newSlug);
            }
        }
    ]
];

However, I noticed a couple of things:

  1. After creating the page, the date field displays a day after the selected date. It seems that’s just what it shows, because the slug is correct.

  2. If I change the date, I get an error message:

The page "jobs/2024-08-11" cannot be found

Although I can see the page updated if I go back to my list of pages.

So it seems that immediately after the slugs gets updated, the “current / old” page ceases to exist as such.

Would you happen to have any pointers on what else could I try to achieve a smoother behaviour?

@javiercuello For future reference: You need to redirect to the new panel page url afterwards:

Code example was wrong. Removed.

@benzin Have I missed something, since when can you redirect from that hook?

You are absolutely right. I ended up solving my (slightly different) issue in the page.changeTitle:after hook. I removed my code snippet, as it would not work!