How to nest block snippets - passing block data from one to another

I have created an image block snippet that works correctly, based on the image block that Kirby ships with it.

I then created a new block that creates a select option in the panel allowing the admin to select a team member from a structure field in the site blueprint. This works as expected, until I wish to do the following:

My structure field contains an image. I wish in my team member snippet to get this image and render it, using the already existing block image snippet. I have tried to create a new Block() object to send from one block snippet to the image block snippet, but I am either transferring no content from one to the other, or in the current state, I am getting an error that the format should be yaml.

Here is my current Team member block snippet

<?php

use Kirby\Cms\Block;

$debugPrefix = '[Teammember Snippet]: ';

$personName = $block->teammember()->value();
if (empty($personName)) {
	monolog()->log('debug', 'Teammember block exists, but selection is empty', [['name' => $personName]]);
	return '';
}

monolog()->log('debug', $debugPrefix . 'person to render', ['name' => $personName]);

$person = $site->team()->toStructure()->findBy('name', $personName);

monolog()->log('debug', $debugPrefix . 'Image found', ['object' => $person->image()]);

$blockData = [
	'content' => [
		'image' => $person->image()->toFile(),
		'caption' => $personName,
		'link' => '',
	],
	'type' => 'image'
];

$blockToTransmit = new Block($blockData);

if ($person) : ?>
	<article class="c-card c-card--person">
		<h2><?= $person->name() ?></h2>

		<? if ($person->description()) : ?>

			<div class="c-card__description">
				<?= $person->description() ?>
			</div>

		<? endif ?>


		<? if ($person->image()) : ?>
			<div class="c-card__portrait">
				<? snippet('blocks/image', ['block' => $blockToTransmit]) ?>
			</div>
		<? endif ?>
	</article>
<? endif; ?>

I am not able to get recreate a block object and send it to the image snippet.

Any tips?

Maybe this already helps: Creating Image Blocks programmatically - #2 by texnixe

Adjusting my block data by using an array inside of the image property properly transmitted the image to my image snippet…

$blockData = [
	'content' => [
		'image' => [$person->image()],
		'caption' => $personName,
		'link' => '',
	],
	'type' => 'image'
];

But the image was not found. I am assuming that because my image belongs to the main content folder (the image is assigned to the site blueprint) and not the page that the block is rendered on, it can’t find the image. Would this assumption be correct?

You should pass the uuid of the file here, so convert to file object first, then get the uuid

Here is an example of the block structure that gets sent from the snippet to the image block snippet. I am sending the UUID, as far as I can tell.

[2024-06-13T11:37:43.465536+00:00] kirby.INFO: [Image Snippet]: receiving data {"data":{"content":{"image":[{"Kirby\\Content\\Field":{"value":["file://l4uiOG016HtCWSFh"]}}],"caption":"Andrea Hoffmann","link":""},"id":"09ca1c31-f6e4-4119-b9bf-c42bd56d7a1b","isHidden":false,"type":"image"}} []
[2024-06-13T11:37:43.465867+00:00] kirby.DEBUG: [Image Snippet]: No image found [] []

What does this return? I’d say a field object, but you don’t want the field object, but the uuid of the file. So should be $person->image()->toFile()?->uuid()?->toString()

1 Like

I just compared the object structure of the normal image field and the teammember field and see the difference in the data structure.

From the standard image component

{
    "data": {
        "content": {
            "image": [
                "file://yK0s1hL6ANWpWxaO"
            ],
            "alt": "my alt",
            "caption": "This is a caption",
            "resizewidth": "",
            "maxwidth": "1800",
            "ratio": "16/9",
            "link": "",
            "target": "_self",
            "alignment": "",
            "margintop": "",
            "marginbottom": ""
        },
        "id": "7f89414b-923b-4262-a1d7-0f9b2748db95",
        "isHidden": false,
        "type": "image"
    }
}

From my block snippet that is sending the block to the image snippet

{
    "data": {
        "content": {
            "image": [
                {
                    "Kirby\\Content\\Field": {
                        "value": [
                            "file://7Wjg9p4B6CpO38Ll"
                        ]
                    }
                }
            ],
            "caption": "Max Mustermann",
            "link": ""
        },
        "id": "ef8c4a39-f1a4-4fb3-9a97-fa31cb5feb6e",
        "isHidden": false,
        "type": "image"
    }
}

What I am sending to the image property is wrong… will need to adjust it.

Thanks for your help thus far.

What you sent me ($person->image()->toFile()?->uuid()?->toString()) worked! Thanks.