Error on page with blocks

Hi,
I have a strange behaviour on my page. I have a onepager where I publish all sections as own page with blocks. And for two pages I need a seperation for this I change the page-collection in the controller. But on the two singlepages I got the error

Call to a member function toBlocks() on null

inside the foreach foreach($section->contentblocks()->toBlocks() as $block): .
If I dump the $section I have a regular JSON in my field so there should parse it with toBlocks() without no problems like on the onepager where I have no problems.

dump of $section:

controller:

return function ($page, $pages, $site, $kirby) {

    $shared = $kirby->controller('site', compact('page', 'pages', 'site', 'kirby'));

    if($page->slug() == 'impressum'):
        $collection = $pages->listed()->find('impressum');
    elseif($page->slug() == 'datenschutzbestimmungen'):
        $collection = $pages->listed()->find('datenschutzbestimmungen');
    else:
        $collection = $pages->listed()->filterBy('slug', '*=', 'sektion');
    endif; 

    if ($site->logo()->isNotEmpty()) :
    	$headerimage = $site->logo()->toFile();
    endif;

    if ($site->footerlogo()->isNotEmpty()) :
    	$footerlogo = $site->footerlogo()->toFile();
    endif;

    $intendedTemplate = $page->intendedTemplate();
    $maintenance      = $site->maintenance()->bool();

    return ['shared' => $shared, 'collection' => $collection, 'headerimage' => $headerimage, 'footerlogo' => $footerlogo, 'intendedTemplate' => $intendedTemplate, 'maintenance' => $maintenance, ];
};

Template:

<?php
$n = 0;

// $maintenance = $page->intendedTemplate() == 'maintenance';
$maintenance = $site->maintenance()->bool();

if (!$kirby->user() AND $maintenance) :
	go('/wartungsmodus');
endif;
?>
<?php snippet('site/htmlheader'); ?>
<main class="main container-fluid">
    <?php foreach($collection as $key => $section):  ?>
            <section class="<?php echo $section->slug() ?>">
        		<?php foreach($section->contentblocks()->toBlocks() as $block): 
                    
                    $blockType = $block->type(); 
                    
                    if($blockType == 'titletext') $n++; 
                ?>
                <?php snippet('blocks/' . $blockType, [
                    'block' => $block,
                    'count' => $n
                ]) ?>
                <?php endforeach; ?>
    		</section>
    <?php endforeach ?>
</main>
<?php snippet('site/footer') ?>

markdown Block:

<div class="blocks <?php echo $block->type() ?> <?php echo $block->id() ?> border-<?php echo $block->textborder() ?>" id="<?php echo $block->id() ?>" style="color: <?php echo $block->palette() ?>">
    <?php echo $block->text(); ?>
</div>

Hopefull I have not missed something

What surprises me the most is that you don’t get an error on $section->slug(), because the content object doesn’t have a slug.

The main issue with your code is the following:

This code returns a single page object, not a collection (even if you name it $collection), which you cannot loop through, whereas

This returns a proper pages collection.

Hence the error.

Always check your return types…

BTW: These if statements (same for headerimage etc.) are superflous. You can just use

$footerlogo = $site->footerlogo()->toFile();

which will then either return null or a file. Because even if the field contains a filename, it doesn’t mean the file exists and can still return null.

Thanks for the Hint.

Whow super! Thanks. I thought i can also loop through the singlepage and it ended direct after because its only one.

What surprises me the most is that you don’t get an error on $section->slug(), because the content object doesn’t have a slug.

I will see whats output. I think null.

Cheers

Why do you make the separation between the two pages and the rest, anyway? If it is a one-pager that loops through all listed pages, you might just keep it as a single collection?

These two pages get his own page and will not displayed inside the onepager.
And I want to use the default template for all pages.

That’s not always the best idea, just leads to unnecessarily complex code with a lot of it statements…

I’m by you, but is this complex code where I have only differend collections or singlepages?
The code inside the template will be the same on all templates because the content is managed through the blocks.

No, it will not be the same. Because for the one pager, you need a loop for the collection. And for the single pages, you don’t want a loop. So then you will start adding if statements to your template to check if you have a page or a collection; and that on top of the if statements in your controller.

It’s up to you, of course, but not very maintainable.

Hi,
yes your right, also in the meanwhile I needed more if statements to print also the pagetitle in some situation and some other stuff.