@texnixe In the Discord, you point me to this cookbook : Quicktip: Add blocks to a blocks field programmatically | Kirby
It’s ok for a block type
fields:
text:
type: blocks
pretty: true
but what if I use a layout type
fields:
layout:
type: layout
I tried this in the config file but it remove all my blocks
'hooks' => [
'page.update:after' => function ($newPage, $oldPage) {
foreach ( $newPage->layout()->toLayouts() as $layout ):
foreach ( $layout->columns() as $column ):
foreach ( $column->blocks() as $block ):
if ( $block->type() === 'image' ) :
$image = new Kirby\Cms\Block([
'content' => [
'url' => $block->image()->toFile()->url()
],
'type' => 'image',
]);
$newblocks = $column->blocks()->add(new Kirby\Cms\Blocks([$image]));
$kirby = kirby();
$kirby->impersonate('kirby');
$newPage->update([
'layout' => $newblocks,
]);
endif;
endforeach;
endforeach;
endforeach;
}
]
1 Like
You would have to create a new Layout object…
Could you please show me a code example ?
I’m afraid I can’t for the moment. You could have a look at the source code, how to construct a new layout object.
@bastianallgeier or @distantnative, could you please help out with this?
The easiest way to create blocks and layouts looks like this:
$blocks = Kirby\Cms\Blocks::factory([
[
'content' => [
'text' => 'Nice heading'
],
'type' => 'heading'
],
[
'content' => [
'text' => 'This is some text'
],
'type' => 'text'
]
]);
$layouts = Kirby\Cms\Layouts::factory([
[
'columns' => [
[
'width' => '1/2',
'blocks' => [
[
'content' => [
'text' => 'Nice heading'
],
'type' => 'heading'
]
]
],
[
'width' => '1/2',
'blocks' => [
[
'content' => [
'text' => 'This is some text'
],
'type' => 'text'
]
]
]
],
]
]);
Ok so if I want to update a field that belongs to all my image type block, I need to rebuild an entire layout object based on my current layout and just change the field concerned then do :
$newlayout = Kirby\Cms\Layouts::factory([
[
'columns' => [
[
'width' => '1/2',
'blocks' => [
[
'content' => [
'text' => 'Nice heading'
],
'type' => 'heading'
] .... ;
$kirby = kirby();
$kirby->impersonate('kirby');
$newPage->update([
'layout' => $newlayout,
]);
I am right ?
Yes, you would basically merge what you have with what you want to change, then update the field with the result.
1 Like
Bringing this thread up instead of a new one. I am updating some values in some blocks which are also inside a Layouts field and am using the above technique to convert an array that holds the layout data structure to a Layouts object.
When doing var_dump all I get is:
object(Kirby\Cms\Layouts)#6106 (1) { [0]=> string(36) "d7fd1505-431c-4926-999f-8cbd6060714b" }
whereas when I am doing the same with the Layouts before processing it I get:
object(Kirby\Cms\Field)#6150 (1) { ["layout"]=> string(666) "[{"attrs":[],"columns":[{"blocks":[{"content":{"text":" ...
Sometimes though I get a full Layouts object through var_dump
also for the first case (post-processing the blocks inside the Layouts field).
Is this a var_dump
oddity?
I am making sure this part works fine as I am then passing the Layouts object to new Kirby\Cms\Blocks
to combine all blocks part of the Builder into one object. If I don’t process the Layouts block then my plugin updates correctly the article, if I pass it the plugin fails to write the blocks collection altogether.