Inheriting fields across page depth

My pages have an hero image. When no image is chosen the parent page should be checked for an hero image. If that’s not the case, the parent parent page should be checked, and so on. If there’s no parent page(s) a fallback image should be used.

The following codes works, but a) this is very likely not the most elegant solution and b) I also want this to work for any page depth (subpage level) without blowing the code up even more.

Any ideas? THANKS! :slightly_smiling_face:

<?php if($image = $page->hero()->toFile()): ?>
<img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">

<?php elseif($page->depth() === 2 AND $image = $page->parent()->hero()->toFile()): ?>
<img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">

<?php elseif($page->depth() === 3 AND $image = $page->parent()->hero()->toFile()): ?>
<img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">

<?php elseif($page->depth() === 3 AND $image = $page->parent()->parent()->hero()->toFile()): ?>
<img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">

(...)

<?php else: $image = asset('assets/img/header-fallback.jpg'); ?>
<img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">
<?php endif ?>

Never repeat the same HTML just because you have different conditions. In this case, determining the correct image to use before, ideally in a custom page method, then output the result.

The page depth is not really relevant, so you would rather check if the page has a parent page.

It’s probably also easier to loop through the $page->parents() collection when trying to find the relevant image.

Yes, but … how? Thanks for the quick reply.

Kirby::plugin('my/page-methods', [
    'pageMethods' => [
        'getHeroImage' => function () {
            $image = $this->hero()->toFile();
            if ( ! $image ) {
                foreach ( $this->parents() as $parent ) {
                    if ( $image = $parent->hero()->toFile() ) {
                      break;
                    }
                }
                if ( ! $image ) {
                    $image = asset('assets/img/header-fallback.jpg');
                }
            }
            return $image;
        }
    ]
]);

Not tested. Not sure in which order the parents are returned, you might have to flip them.

Then in template:

<?php if ( $image = $page->getHeroImage() ) : ?>
    <img srcset="<?= $image->srcset('header') ?>" sizes="100vw" src="<?= $image->thumb('header')->url() ?>">
<?php endif; ?>

Works great, thanks again for your time!