Nesting blocks inside a structure

Is this possible?

Blueprint code:

fields:
  content:
    label: Content
    type: structure
    fields:
      sectionBlock:
        label: Sections
        type: blocks
        fieldsets:
          - heading
          - text
          - image
          - list

Template code:

<?php
$sections = $page->content()->toStructure();
foreach($sections as $section): ?>
    <?php foreach($section->sectionBlock()->toBlocks() as $block): ?>
        <div id="<?= $block->id() ?>" class="block <?= $block->type() ?> <?= $block->level() ?>">
            <?= $block ?>
        </div>
    <?php endforeach ?>
<?php endforeach ?>

I couldn’t find a detailed example of this combo in the docs, however, it seems to display OK in the panel. See screenshots:


I think the problem is in the template code. I’m not sure how to call the block content and get it to display on the page, currently stuck with this error:

Error thrown with message "Call to a member function sectionBlock() on null"

Is there something I’m missing?

Otherwise, I’m thinking the alternative will be to make this a Nested Block instead.

Would love to hear any thoughts/advice!

Thanks

The problem is in this line. Because you are using a reserved name for your field, $page->content() returns a Content object. So either rename your field or call it via

$sections = $page->content()->get('content')->toStructure();
1 Like

Wow, classic oversight.

Thanks so much! This works perfectly

Hi again @texnixe

In addition to the above, I ended up reconfiguring the above to make use of Nested Blocks as the resulting CMS is a bit cleaner. This required creating a plugin to link it up.

The blocks are showing up fine (heading, text, image, list) However, the table structure is not printing.

Have been playing around with this for a couple of hours with no luck.

Template code (about.php):

<section class="content">
    <?php
    foreach($page->content()->get('content')->toBlocks() as $nestedBlock):
    snippet('blocks/' . $nestedBlock->type(),[
        'block' => $nestedBlock,
        'layout' => $nestedBlock->layout()->value()
        ]);
    ?>
    <?php endforeach ?>
</section>

Plugin code (section.php):

  <div class="blocks">
    <?= $block->sectionBlocks()->toBlocks() ?>
    <?php 
    $rows = $block->rows()->toStructure();
    if($rows->isNotEmpty()):
    ?>
    <table class="table">
      <?php foreach($rows as $row): ?>
        <tr>
          <td><?= $row->name()->html() ?></td>
          <td><?= $row->role()->html() ?></td>
          <td><?= $row->year()->html() ?></td>
        </tr>
      <?php endforeach ?>
    </table>
    <?php endif ?>

Blueprint (blocks/section.yml)

name: Section
icon: add
fields:
  title:
    type: text
    required: true
  sectionBlocks:
    label: Blocks
    type: blocks
    fieldsets:
      - heading
      - text
      - image
      - list
      - table

Blueprint (blocks/table.yml)

name: People
icon: menu
preview: table
fields:
  rows:
    type: structure
    columns:
      name:
        width: 1/3
      role:
        width: 1/3
      year:
        width: 1/3
        align: right
    fields:
      name:
        type: text
        width: 1/3
      role:
        type: text
        width: 1/3
      year:
        type: number
        width: 1/3
        align: right

Maybe it has something to do with layouts, or maybe custom fieldsets?

Hope it’s ok to add this to the thread… it’s more or less related. Greatly appreciate your thoughts/advice!

Ah, figured it out as per this thread: How to enable table block? - #3 by toddz

I was missing “snippets/blocks/table.php” in my snippets folder.

Snippet (snippets/blocks/table.php)

<?php 
$rows = $block->rows()->toStructure();
if($rows):
?>
<table class="table">
    <tr>
        <th>This snippet is linked!</th>
    </tr>
    <?php foreach($rows as $row): ?>
        <tr>
        <td><?= $row->name()->html() ?></td>
        <td><?= $row->role()->html() ?></td>
        <td><?= $row->year()->html() ?></td>
        </tr>
    <?php endforeach ?>
</table>
<?php endif ?>

Plugin (plugins/section-block/snippets/blocks/sections.php)

<div class="row <?= $block->title()->lower() ?>">
  <div class="title">
    <h2><?= $block->title() ?></h2>
  </div>
  <div class="blocks">
    <?= $block->sectionBlocks()->toBlocks() ?>
  </div>
</div>

Blueprint (blueprint/blocks/section.yml)

name: Section
icon: add
fields:
  title:
    type: text
    required: true
  sectionBlocks:
    label: Blocks
    type: blocks
    fieldsets:
      - heading
      - text
      - image
      - list
      - table

Blueprint (blueprint/blocks/table.yml)

name: People
icon: menu
preview: table
fields:
  rows:
    type: structure
    columns:
      name:
        width: 1/3
      role:
        width: 1/3
      year:
        width: 1/3
        align: right
    fields:
      name:
        type: text
        width: 1/3
      role:
        type: text
        width: 1/3
      year:
        type: number
        width: 1/3
        align: right

Hope this helps!