I have a blocks field that contains several blocks, all of the same type.
Now I want to run a function on page update to “calculate” and update a field of each block.
For a simple example let’s say my blocks have a firstname() field and a lastname() field and whenever I change the page (for simplicity), I want to calculate all the values of a third (hidden) field that is fullname().
How could I do this. I know I need to use a page.update:after hook, but how exactly can I take the values of the existing blocks, alter one of these values and then write it back to the blocks field?
Because I don’t need this on output, but in the panel, on the block’s label instead. Apparently I cannot use queries there (but can just read out plain field values instead), so I somehow need to write this information into a field directly.
I have done this with builder fields in the past, but since the builder plugin is now replaced by blocks, I need to get it to work with blocks. However, I have no idea how to convert them and update them.
Yes, I have seen that one, as well as a few posts on creating blocks programmatically, hence why I am now asking how to update existing blocks programmatically.
There must be some way to update an existing block? I mean, how would I go about this theoretically? Read the blocks field in its entirety, convert it to … an array? … or YAML? Then replace one of the fields and use the page update method to write the result back to the field.
I just do not know: What format do I need to convert the blocks field to? How do I then update one of the fields? I am having a hard time imagining that this is harder then creating a custom block preview. Don’t really wanna deal with Vue.js.
Ok, my specific scenario was more complex, but I managed to customize my block preview now and have now a result which is quite a bit more advanced than would have been possible with parsing some label text.
However, I now have the problem that I would love to automatically sort the entries of this block field by date. So I’m afraid I do need to update the block fields contents via a hook after all (correct me, if my assumption is wrong).
However, I would just need to read the blocks contents, sort them by a field, and then write it back, which to me sounds a bit easier than updating a field value in the process. However, I still do not know how I have to convert the blocks.
I have tried this:
'page.update:after' => function ($newPage) {
if ($newPage->intendedTemplate() == 'project') {
$sortedBlocks = $newPage->eventblocks()->sort('date');
$newPage->update([
'eventblocks' => $sortedBlocks
]);
}
}
But it does not change anything on updating the page. Any idea what formatting I have to do to make this work?
I found this threat looking for the same thing. My use case is that I built a very simple form editor using blocks where I want to store the input data in the block.
Edit: Didn’t work. Fields turned into default text fields. Found this hint by @texnixe, that you have to covernt the blocks object into an array when storing it: