Related content on the panel

I’m trying to achieve something similar to related pages on the panel. I checked the documentation and I’m still not quite sure how to come up with a proper query. This is my scenario:

  1. I have a job offer page
  2. I have a company page
  3. From the job offer page, I can select a company page

Now, what I would like to do is in the company blueprint, automatically display job offers that have that company selected in the company field.

For reference, this is how the job blueprint looks like in this regard:

    fields:
      company:
        label: Company
        type: pages
        query: site.find('companies')

According to my gpts, “this is a complex data relationship and Kirby wasn’t made for that”. So I wanted to validate this feedback.

The important bit is to display these job offer pages automatically from the company page in the panel, not via manual selection.

You can use a pages section with a query that filters all job offers by the company field.

Thank you. I’ve been trying something like this, to no results.

  related:
    label: Related Pages
    type: pages
    query: site.find('jobs').filterBy('company', $page->id())

Logic is that in children of “jobs”, find the ones that share the same id than the current page. But that doen’t seem to be working to retrieve anything.

you cannot use php syntax inside blueprints, also, a pages field stores the uuid, not the id

Thank you. I will keep exploring. Nothing I have tried seems to be working, and I haven’t found any other examples / documentation so far. Will keep digging.

The main problem is that the pages field might store references to pages in many formats.
A job might save its reference to the company in any of the following formats (in the content txt file):

Company: companies/fuller-design-systems
Company: 
  - companies/fuller-design-systems
Company: 
  - page://kasje23j90032dnm0xnd320

(or possibly more combinations).

So there is no straightforward way to filter pages by their reference to a page, as those references first need to be dereferenced to actual page objects.

I’d suggest you create a Page Model for the Job pages. Page models help you customize the functions that a certain type (aka template) of pages offer, then you can filter by the result of that function.

For example this could look like this:

site/models/job.php:

<?php 

use Kirby\Cms\Page;

class JobPage extends Page {
    /**
    * Dereference the company field
    */
    function companyPage(): ?Page {
        return $this->company()->toPage();
    }
}

Then you can filter by that function

query: site.find('jobs').children.filterBy('companyPage', page)
#                       ^^^^^^^^^                  ^^^^   ^^^^

PS: Notice you also need to call filterBy on the children of site.find('jobs') and not directly on the “jobs” page itself.

Thanks @rasteiner ! I didn’t know about Page Models. This is pretty much what I wanted. What I’m not sure if it’s possible in Kirby is to avoid the select modal step, and have those pages displayed directly (without the manual association).

I’m not sure if that makes sense, from the tool’s point of view — although would be helpful to me.

That sounds like you’re not using a pages section, but a pages field.
In the company page blueprint you should be using a pages section.

title: Company

columns:
  main:
    width: 2/3
    sections: 
      fields:
        type: fields
        fields:
          info:
            type: info
            text: Here are your fields
  aside:
    width: 1/3
    sections:
      jobs:
        label: Jobs
        type: pages
        query: site.find('jobs').children.filterBy('companyPage', page)
        create: false

However, rethinking the whole situation, it sounds like you have a “one to many” relationship here (many job offers belong to only one company, I think). Therefore it could make sense to have the job offers be children of the company pages. That would kind of make it easier, I think.

@rasteiner What you mentioned makes sense, I could have company pages, and jobs are child of a respective company — since a company can have multiple jobs.

However, I’m struggling to follow this approach in implementation, since I understand that child pages cannot be created from a company’s blueprint.

Should I have both /jobs and /companies at the same level in the content folder, and then just link a company to a job?

I understand that in that case, from the company’s page I would only be able to list “linked” jobs and not do anything else.

Am I correct?

That was the idea of the suggested approach, yes.

This section would then list all job children which are linked to the current company.

@texnixe

Would there be any caveats from creating a job as hierarchical child of a company? I thought this was not possible, but I just tested this in my company blueprint:

title: Company page

columns:
  main:
    width: 2/3
    sections:
      jobs:
        type: pages
        template: job

That creates this in my content folder

/company/job 1/job.txt

As a side note, on my home.php template later on I’ll need to display all jobs across companies by date they were posted, so I’m curious if either approach will make that more or less convenient.

Yes, that’s also possible, of course. Whatever structure suits your project best. It doesn’t matter if you sort all children of a page called jobs, or of a collection of pages fetches from all the company pages, as long as the pages have a date.

I understand. I appreciate your help and support as I continue learning Kirby. I will experiment with these approaches. Thank you!