toStructure() error in Kirby V4

Migrating from V3 to v4. I have Kirby website with a nested block structure, which allows me to customise/build a website from block components. Upon migration, it seems that couple of blocks (not the custom block created via plugin) but just regular blocks cannot be converted to structure.

Here is the code example:

<?php foreach ($block->accordion()->toStructure() as $index => $accordionItem) : ?>
                    <?= $accordionItem->description()->kt() ?>      
        <?php endforeach; ?>

It gives me error:

Kirby\Content\Content::__construct(): Argument #1 ($data) must be of type array, string given, called in /kirby/src/Cms/StructureObject.php on line 40" in block type: "card_accordion"

Here is how I deal with those nested blocks in a template:

<?php
// Loop through the main blocks
foreach ($page->blocks()->toBlocks() as $block) :
    if ($block->type() !== 'section') continue;
?>

<section id="<?= $block->id() ?>" class="<?= $block->bgcolour()->html() ?> px-3 py-18 sm:py-32 sm:px-0">
    <div class="container">
        <div class="mx-auto max-screen-md xl:max-w-screen-xl">

            <?php
                // Loop through the nested blocks
                foreach ($block->blocks()->toBlocks() as $nestedBlock) :
                    switch ($nestedBlock->type()) {
                        case 'snippet_injector':
                            snippet($nestedBlock->snippetname()->value());
                            break;
                        case 'scans_collection':

                            snippet('product_layout', ['nestedBlock' => $nestedBlock]);

                            break;
                        default:
                            echo $nestedBlock;
                            break;
                    }
                endforeach;
                ?>
        </div>
    </div>
</section>

<?php endforeach; ?>

The error arises from a simple $accordionItem = $block->accordion()->toStructure() and if I do var_dump on $accordionItem I get error. The $accordionItem = $block->accordion()->toYAML() works fine which gives me this structure:

And below is the .txt file output

Note: everything works fine on V3 kirby. I suspect this is something to do how the structured data is being handled in v4? Any ideas ?

I know that the structure in txt files must be OK because 1) it works on kirby v3 no problems.

The other clue is that if i do $block->field()->toStructure() within a custom block (as a Plugin) then it works fine.

Thank you

Somehow I’m missing some information. So you have nested blocks, and inside those nested blocks you are using a structure field? What sort of field are you calling toStructure() on? Please post the relevant blueprints.

This accordion field I don’t seem to see in the text file snippet you posted above?

What also confused me is that you write

although these are custom blocks…

Hi texnixe,
Yes - it is a nested block within a block which contains a structured field.

This is the blueprint:

title: Card Accordion
icon: 📄
fields:
  header:
    type: text
    label: Header
  description:
    type: textarea
    label: Content
  accordion:
    type: structure
    label: Accordion Sections
    fields:
      title:
        type: text
        label: Title
      iconClose:
        type: text
        label: Close Icon URL
      iconOpen:
        type: text
        label: Open Icon URL
      description:
        type: textarea
        label: Content

And this is the .txt file of the content:
Blocks: [{"content":{"title":"Who is it for","bgcolour":"bg-white","blocks":"[{\"content\":{\"header\":\"\",\"description\":\"\",\"accordion\":[{\"title\":\"\",\"iconclose\":\"fa-circle-plus\",\"iconopen\":\"fa-circle-minus\",\"description\":\"\",\"content\":\"Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.\"}]},\"id\":\"77dc50d3-6cb0-4e66-a68f-81eacaa63599\",\"isHidden\":false,\"type\":\"card_accordion\"}]"},"id":"0c1a3452-a675-49bf-af15-229a685b9689","isHidden":false,"type":"section"}]

Regarding this:

that couple of blocks (not the custom block created via plugin) but just regular blocks cannot be converted to structure.

Sorry, it is just my bad wording. I don’t know the difference between Custom blocks as a plugin and just regular custom blocks. These are regular custom blocks - not plugin custom blocks.

Thanks, if you need more information let me know I will provide whatever to solve this problem!

Vito

Could you please post the blueprint for this blocks field setup?

Hi texnixe,

Ah, of course!

This is a custom plugin block where I can pull all of the nested custom blocks if that makes sense. So as you can see, the “blocks” field and within that there “card_accordion” block.

name: Section
icon: layer
content:
fields:
  title:
    label: Section name
    type: text
  bgcolour:
    label: Background Colour
    type: text
  customClass:
    label: Custom Padding
    type: text
  blocks:
    label: Blocks
    type: blocks
    fieldsets:
      - masonry_cta
      - team_members
      - quotes
      - card_accordion

Thank you for your help
Vito

I could reproduce the error with the content you posted, but creating a new section block works fine. Couldn’t pinpoint what exactly causes this, though.

Hi texnixe,

That is very true - if I make a new block with card_accordion block then it seems to work! I guess I will have to just manually re-do some of those blocks that give me errors. The only problems that I have quite a lot of pages using the same block structure lol. Not sure as well what exactly causes the problem, because V3 Kirby is completely fine. Thanks for you help - really appreciate!

Best wishes,
Vito

Maybe try to recreate the same structure and text as in the Kirby 3 example and compare using a diff tool, I somehow didn’t spot it, maybe you can.

Nevertheless, this sounds like a regression, manually recreating those fields sounds like a lot of work.

I’m having the same issue with K4 and the structured data field inside a blocks field.

My setup is the same:

  • page with blocks field
  • custom block with a structure field within
  • rendering the block template causes an error when calling ->toStructure()

Is this maybe related to the blocks content being stored as JSON and the structure might expect YML?

1 Like

Ok I think I found out where the problem comes from. My accordion block blueprint contained a field called “content” which had some “Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus” content in it. Then I removed this field from the blueprint, but the content still persists within the .txt file. This works well in V3.9 but since upgrading, for some reason this “content” field in the txt file causes an error. This is a comparator:

If I remove this line:
,\"content\":\"Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.\" Then it solves a problem.

Now the question is - why it causes an error in V4 but not in V3.9?

If I reintroduce the old blueprint with

 content:
        type: textarea
        label: Content

and then delete that “Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus” via panel - the error still persists because the txt file still keeps this "content":\ parameter there.

However, If I rename ,"content":"Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus.Loreum ipsum sanctus." To another name, like contento - it solves a problem. Is this to do with some kind of a system name “content” within structure field?

1 Like

Might be. There have been some changes to the Structure field, but I can’t tell, from the information in the changelog, what exactly this involves.

Ah yes thanks for the hint! Had the same problem migrating a structure from v3 to v4. Had a field named content inside the structure which caused the problem and just renamed that field to fix it.