Hook to create duplicate in page folder on edit

Hello,

We are trying to add a hook that would do the following:

  • Create duplicate on page edit
  • Create a sub-folder in the page folder
  • Add the duplicate to this sub-folder
  • Every time there is a new edit, it should create a unique duplicate in the same sub folder

We have tried to create a hook, but it doesn’t seem that it allows to create easily a sub-folder and add the page duplicate to it…

'hooks' => [
    'page.update:before' => function ($page) {
        $historyPage = $page->createChild([
            'draft'=> false,
            'content' => [
              'title'  => 'history',
            ]
          ]);          
          $historyPage -> createChild([
            'draft'=> false,
            'content' => [
              'title'  => $page->title(),
              'content' => $page->content()
            ]
          ]);  
    }
]  

We thought about doing it this way -> on page edit create a sub-folder for this page, and then create a child in this sub-folder that contains the info of the original page… It creates the sub-folder, but the second part doesn’t work.

Checked the hook documentation, but it’s not helping much :frowning:

Hope you can help!

Cheers

I don’t think you can do this in a before hook, but have to use an after hook. Note that the old page status is still available to you in an after hook.

Thank you! We used this, and my partner came up with a solution that seems to work !

'hooks' => [
    'page.update:after' => function ($newPage, $oldPage) {
        // Declaring $historyPage, and finding subfolder "history"
        $historyPage = $oldPage->find('history');
        // If "history doesn't exist, we create it under current folder (child)
        if ($historyPage == null) {
            $historyPage = $oldPage->createChild([
                // We make sure it's not as a draft
                'draft' => false,
                'content' => [
                    'title'  => 'history',
                ]
            ]);
        }
        // We are getting the current time
        $date = new \DateTime('now');
        // This is the time format we will use for naming the copy
        $dateAsString = $date->format('D d M Y_H:i:s');

        //We are creating a child under "history"
        $historyPage->createChild([
            // We make sure it's not as a draft
            'draft' => false,
            // For the content, we use the content of $oldPage, and for the title with use the current date/time
            'content' => $oldPage->changeTitle($dateAsString)->content()->toArray()
        ]);
    }
]

oh, actually it replaces the current title. Gonna try to fix that

I actually changed it to :before, and now it keeps the current title, and modifies it only for the history pages :slight_smile:

    'hooks' => [
    'page.update:before' => function ($page) {
        // Declaring $historyPage, and finding subfolder "history"
        $historyPage = $page->find('history');
        // If "history doesn't exist, we create it under current folder (child)
        if ($historyPage == null) {
            $historyPage = $page->createChild([
                // We make sure it's not as a draft
                'draft' => false,
                'content' => [
                    'title'  => 'history',
                ]
            ]);
        }
        // We are getting the current time
        $date = new \DateTime('now');
        // This is the time format we will use for naming the copy
        $dateAsString = $date->format('D d M Y_H:i:s');

        //We are creating a child under "history"
        $historyPage->createChild([
            // We make sure it's not as a draft
            'draft' => false,
            // For the content, we use the content of $page, and we change the title to the current date
            'content' => $page->changeTitle($dateAsString)->content()->toArray()
        ]);
    }
]

Make sure to use a route to prevent access to these pages for website visitors.

1 Like