Pages field with database connection

Hi there,

I’m currently trying to build a website with a connection to a MySQL database. Thanks to the few courses found on the website, the whole thing is working quite well and I’m reading and writing the content of the pages in a very handy way through the database.

Though, I can’t figure out how to work with the Pages field in that case. I have tables in my DB for many-to-many relationships that makes it quite easy to retrieve the pages I want (for example, the artists for an artwork). But I can’t manage to find the way to show those pages in a Pages field on the back-office interface.

I tried with Pages collections and arrays of pages IDs, but none of those two solutions happened to work.

Am I missing something here?

Thanks in advance!

Do these related pages actually exist in your Kirby installation? How are they stored? The pages field only works with either “real” (=exist in file system) pages or virtual pages, but for virtual related pages you would also need models.

These related pages are virtual pages created from the database too with a page model, yes. So they have a page ID, a slug, and I do retrieve them as Page when I get the data on the front-end. But I can’t find a way to show them as a list of related pages in a Pages field in the back-office.

What does your model that included the related pages currently look like?

To populate the pages field, you have to pass an array of page ids as value.

Well, unfortunately, I can’t make it work by passing an array of page IDs.

This is the model for the parent page:

<?php
class WorksPage extends Page
{
  public function children()
  {
    $works = [];
    foreach (Db::select('work') as $work) {
      $works[] = [
        'slug' => $work->slug(),
        'num' => $work->status() === 'listed' ? 0 : null,
        'template' => 'work',
        'model' => 'work',
        'content' => [
          'db_id' => $work->id(),
          'title' => $work->title(),
          'status' => is_null($work->status()) ? 'draft' : $work->status(),
          'artists' => $work->artists()
        ]
      ];
    }

    return Pages::factory($works, $this);
  }
}

This is the artists() function in the child model that create the array of IDs from the database:

  public function artists()
  {
    $connections = Db::select('intervention', 'artist_id', 'work_id = ' . $this->db_id())->values();
    $artists = collection('artists')->filterBy(function ($artist) use ($connections) {
      return in_array(strval($artist->db_id()), array_column($connections, 'artist_id'));
    })->map(function ($artist) {
      return $artist->id();
    })->values();
    return $artists;
  }

When I print $page->artists() on a child page, I do have an array of page IDs. But the artists Pages field on the back office still looks empty.

What does the blueprint definition for the artists field look like?

Nothing in particular, I removed every unnecessary property to avoid any problem at the moment.

fields:
  artists:
    label: Artistes
    type: pages

But I just understood where the problem is. I actually call the artists() function from the child model in the parent model before the element from the array is transformed into a page. So it can’t work, obviously!
Thanks for your help!

But your field should also query the children of the artists page, not of the current page.