Populate page with default blocks when changing template

Iā€™m going to share my solution here hoping it will help somebody with the same use case.

I had to convert hundreds of articles in different categories to different blueprints with the blocks field. Depending on the category the blocks field must be populated with different default blocks. In the blueprint this is very straightforward:

blocks:
  default:
    - type: date
      content:
        date: '29.12.2020'
    - type: hr
      content:
        color: '#FCCD2E'
    - type: h1
      content:
        text: '<strong>Bold text</strong> elit non mi porta gravida at eget metus.'

But because the default values are only triggered on page creation I had to add a page.changeTemplate hook to populate the blocks field on template changes:

'hooks' => [
    'page.changeTemplate:after' => function ($newPage, $oldPage) {
        // Check if blocks field is empty
        if($oldPage->blocks()->toBlocks()->isEmpty()) {
            // Get default values from blueprint of $newPage
            $default = $newPage->blueprint()->field('blocks')['default'] ?? array();
            $blocks = array();
            foreach($default as $defaultBlock) {
                $blocks[] = $defaultBlock;
            }
            // Update page with JSON encoded array of default content
            $newPage->update([
                'blocks' => json_encode($blocks),
            ]);
        }
    }
]

You could of course also use this code to automatically iterate over every page. I need to manually edit some things so the changeTemplate trigger suits this use case very well.

4 Likes