How to change page content in `page.update.before` hook?

I’m developing a plugin that adds IDs to structure field entries. However, I have trouble saving the modified data. Here’s my plugin hook:

'hooks' => [
  'page.update:before' => function ($page, $values, $strings) {
    foreach ($values as $key => $field) {
      if (is_array($field)) {
        fillIds($field);

        $page->update([
          $key => yaml::encode($field)
        ]);
      }
    }

    $values['test'] = 'foo1'; // does nothing
    $strings['test'] = 'foo2'; // does nothing

    return [
      'test' => 'foo3' // does nothing
    ];
  }
]

As you can see, I try 4 ways of updating the page. If I call $page->update(), it does nothing, probably because Kirby detects it would cause and endless loop due to the hook? If I change the $values and $strings array, nothing happens (I tried specifying them as references in the arguments but I get errors). Finally, if I return an array, still nothing happens.

How am I supposed to update the page? I could use page.update.after but I think it would be less efficient. Also, I don’t get the $values arguments which is not so convenient.

@texnixe has built a similar plugin for Kirby 2 and it uses the $page->update() method. That does work in page.update.after, but not in page.update.before where I need it.

How do I update the page content in page.update.before?

Before hooks do not let you modify the incoming data. They give you the option to do something before the values are actually saved to disk. Like intervening the save action by throw new Error('Oops') or perhaps clear a cache. In your case you would probably need to use the page.update:after hook and update any structure item that does not have an id yet in there.

2 Likes