Create relationship between pages in panel

Hello,

I am creating a website, which will be utilised in 2 ways.

  1. Organisation will upload information regarding Artists, Artworks & Exhibitions into panel. They will also include note fields here that are hidden from front end. Organisation will use panel for both editing content AND general research, reading of content.

  2. Public will access information from front end.

The structure will be:

Site
  Artists
    Artist
  Artworks
    Artwork
  Exhibitions
    Exhibition

An artist will be linked to their artwork pages, which can be done via a pages field.

I was wondering if there was a way to then reflect this page relationship on the artwork page automatically? Perhaps with a query?

I am trying to set this up as it will be important for staff members who view the site primarily through the panel to know what artist/s made the artwork.

Also, trying to keep it as DRY as possible for content editors.

Thank you!

Pages sections don’t allow for queries. But you could create separate sections for artworks by artist in the artworks page with a combination of the pagesdisplay section (plugin: https://getkirby.com/plugins/rasteiner/pagesdisplay) and dynamic blueprints (Add programmable blueprints recipe by texnixe · Pull Request #1569 · getkirby/getkirby.com · GitHub)

Hi @texnixe, thanks for the lead.

I have tried resolving it a different way, but am running into an error.

On the “Artwork” page I have the below field:

artist:
  type: pages
  query: site.children.template('artists').children.template('artist')

I am using this model for artist.php:

<?php

class ArtistPage extends Page
{
    public function getArtworks()
    {
        $artworks = site()->index()->filterBy('intendedTemplate', 'artwork');
        foreach ($artworks as $artwork) 
        {
            $made_by_artist = $artwork->filterBy('artist', $this->uid());
            if ($made_by_artist->count() > 0)
            {
                return array_unique($made_by_artist);
            }
        }
        return false;
    }
}

With this section being on the “Artist” page (using the pagesdisplay plugin):

  artworks:
    headline: Artworks
    type: pagesdisplay
    query: page.getArtworks

I am getting this error:

The section “artworks” could not be loaded: Object of class Kirby\Cms\Field could not be converted to int

I am guessing I have not written the model properly?

This line doesn’t make sense. $artwork is a page object which you cannot filter. What do you want to do here?

I guess I am trying to look through all Artwork pages and filter by Artist selected in Artist field.

eg.

If Artwork A, Artwork B & Artwork F all have the page “John Citizen” selected in their Artist fields, then Artwork A, Artwork B & Artwork F will be returned in the page model.

:grimacing:

Then you have to apply the filter on the $artworks:

 public function getArtworks()
    {
       return site()->index()->filterBy('intendedTemplate', 'artwork')->filter(fn ($artwork) => $artwork->artist()->toPages()->has($this);
    }
1 Like

Thanks so much, that works perfectly.

Hi @texnixe, I am working on another site that I am trying to create relationships between Artists, Artworks, Exhibitions etc (like in the previous comments). I noticed that the pagesdisplay-section plugin had been archived by the author. I was wondering if its functionality has been incorporated into Kirby’s core in version 4?

Got around to checking today, and yes it is working fine with just the pages section:

exhibitions:
  headline: Exhibitions
  type: pages
  query: page.getExhibitions
  create: false
  sortable: false