Automatic title field from date field

I’m trying to create a kind of blog where page titles are not really used. Since the title is required for every page, I thought it might be a good idea to auto-generate it from the date. I’m wondering if this is possible.

I have set up this hook in config.php:

<?php

return [
    'debug' => true,
    'hooks' => [
        'page.create.after' => function ($page) {
            if ($page->template() == 'entry') {
                $newTitle = $page->createdAt()->toDate('l, j F Y');
                $page->changeTitle($newTitle);
                $page->changeSlug(str::slug($newtitle))
            }
        }
    ]
];

However this results in a blank page (frontend and backend). What am I doing wrong?

Wouldn’t it make more sense to use the Custom Add field plugin?

Ah right, I see how I can use this plugin to set the title automatically by skipping the dialog.

I am just curious, though, was there something wrong with my hook? Because I would also like to automatically change a page status to listed, but $page->changeStatus('listed') does not work.

In any case thank you!

Should be page.create:after, with a colon.

Ah right, of course. It still leads to a blank page, but I guess for the title I can just use the plugin. However, since $page->changeStatus('listed') also doesn’t work, I must be doing something wrong. I haven’t been able to find any examples in the docs of how to actually write one of these hooks, so maybe I’m looking in the wrong place.

There’s also a semi-colon missing after that line…

Other than that, $page->changeStatus('listed'); should work just fine.

This works! Only after the page creation, the title is changed, but the panel still tries to send me to the old page, which then is not found. Is there a way for the hook to redirect me to the new page?

Hm, that’s strange, if you change the slug, yes, but changing the title only shouldn’t have such an effect. Are you using the plugin now?

This is without the plugin—just changing the title and slug with the hook that I wrote. I suppose I could leave out changing the slug so that it would still work.

Yes, changing the slug from a hook is not such a great idea, because there is no way to redirect to the new location within the hook.

Ah right, thanks.

That’s why I suggested using the plugin… gives you more freedom without having to use page.create:after hooks.

Yep, I am probably going to use both—the plugin for the title/slug and the hook to change the status to listed. In any case, thank you again for all your help!

1 Like

Sorry to bother you again, but I was thinking setting the title and slug as a unix timestamp would work—they would function kind of like UUIDs. So I’ve been trying to enforce this for all posts, through a page.update:after hook. However, slugs and titles do not seem to change with the code below. Am I doing something wrong?

<?php

return [
    'debug' => true,
    'hooks' => [
        'page.create:after' => function ($page) {
            if ($page->template() == 'entry') {
                $page->changeStatus('listed');
            }
        },
        'page.update:after' => function ($newPage, $oldPage) {
            if ($newPage->template() == 'entry') {

                $oldTitle = $newPage->title();
                $newTitle = $oldPage->createdAt()->toTimestamp();
                $newSlug  = str::slug($newTitle);

                try {

                  $updatedPage = page($oldTitle)->update([
                    'title' => $newTitle,
                    'slug'  => $newSlug, 
                  ]);

                  echo 'The page has been updated:';

                } catch(Exception $e) {

                  echo $e->getMessage();

                }
            }
        }
    ]
];

This doesn’t make sense, should be $newPage->update(). The $oldTitle variable is not needed here.

You will run into the same issue as before when updating the slug from the hook…

Ah of course. Thank you!

However with $newPage->update() nothing seems to happen either…

You will run into the same issue as before when updating the slug from the hook…

Right—I wasn’t sure if this would happen, so I thought I would try it out and see what happens.

Sorry, I’m not fully awake yet, to change the slug, you have to use $page->changeSlug()and $page->changeTitle() to change the title.

That’s what I had been trying before:

<?php

return [
    'debug' => true,
    'hooks' => [
        'page.create:after' => function ($page) {
            if ($page->template() == 'entry') {
                $page->changeStatus('listed');
            }
        },
        'page.update:after' => function ($newPage, $oldPage) {
            if ($newPage->template() == 'entry') {

                $oldTitle = $newPage->title();
                $newTitle = $oldPage->createdAt()->toTimestamp();
                $newSlug  = str::slug($newTitle);

                try {

                  $newPage->changeTitle($newTitle);
                  $newPage->changeSlug($newSlug);

                  echo 'The page has been updated:';

                } catch(Exception $e) {

                  echo $e->getMessage();

                }
            }
        }
    ]
];

However nothing seems to change.

Hm, I think using a page model which overrides the create() method probably makes more sense here than the hooks. Don’t know if it works with the before hook as suggested by @distantnative

Good luck and happy holidays!

1 Like