Query first image from a page OR subpage


I’m having a bit of trouble with querying images in the panel. I’d like to have cover images for my pages section. That section looks like this:

      type: pages
        layout: cards
        size: large
          query: page.images.sortBy('sort', 'asc').first
          back: black
          cover: true

This works perfectly well on most of my pages. However, some pages only have an image in their children. In those cases, this other query works great:

query: page.children.first.images.sortBy('sort', 'asc').first

Is there a way to combine the above two queries into one?

FWIW, trying to use .or() didn’t work:

query: page.images.sortBy('sort', 'asc').first.or(page.children.first.images.sortBy('sort', 'asc').first)
1 Like

You can achieve that with a page model that returns the image, similar to the cover method in the Starterkit: https://github.com/getkirby/starterkit/blob/master/site/models/album.php

I can see why page model makes sense for the photography/album pages in the Starterkit.

The pages section I included above is in my site.yml file. The children that I list are all from the root of the project and they each have unique templates / page types. info, announcements, etc.

Can a single page model be applied across multiple page types? Or is there another option? I’m not quite sure what to even name the model in this case.

Then you need a general page method instead, something like

Kirby::plugin('my/page-methods', [
    'pageMethods' => [
        'getPagePreview' => function () {
           return $this->images()->sortBy('sort', 'asc')->first() ?? $this->children->first()->images()->sortBy('sort', 'asc')->first();         

You should check if the page has children though…

This is great, thanks for pointing me towards page methods.

Just a slight edit:

return $this->images()->sortBy('sort', 'asc')->first() ?? $this->children()->first()->images()->sortBy('sort', 'asc')->first();

Eventually, yes will loop through children with the proper checks in place.