Dynamically fetch corresponding title to structure

Hey there,
I’m using a structure field to get an overview of my website and manage categories.
I can create a new row that is a new category.
In the second column of that row, I would like to display the corresponding projects.
So I though about a query that would match the title of that category, but it seems out of bound for a query.
Maybe something else?

Something like :

title: Site

sections:
  content:
    type: fields
    fields:
      structure:
        label: Structure
        type: structure
        fields:
          action:
            label: Action
            type: text
          projects:
            label: Projects
            type: query
            query: site.find('title of the action in that row')
      pages:
        label: Projets
        type: pages
        query: site.page("projets").children

Thanks.

Your projects field is missing a field type. But apart from that you won’t be able to read the value of the action field on the fly (at least not without some custom solution).

And what could be the custom solution ? Looking into page methods, or something like that?

I’m bumping it,
since I would really like to find a way to do it.
Also, maybe it woud be simpler to do another one, linked to the first idea :
I would like to be able to select a category for a project in the panel, using the type: select
And at the bottom, display all the items with the same categorie as the one selected in the dropdown.

Maybe it’s a bit complex to make it without reloading the page though.

You are trying this inside a structure field. So the challenge would be to fetch the action of the right item in your blueprint, which is impossible.

The only way this could work on the blueprint side would be if you save first and then write the result to file using a hook.

This is probably not what you want. So you would have to do this in the Panel Vue part, with a custom (structure) field where the second field listens to the first.

If this is supposed to be an overview of your site, wouldn’t it make more sense to either use an info field that calculates all that and displays a table? Or even a custom panel area with a list/table. I don’t really see the advantage of trying to do this in a structure field. Might be missing something.

Or maybe I’m the one missing something ! Surely a table view would be easier.
Do I need to check for a hook that listen to the left column in order to display the corresponding content in the right?

A hook will only work when you actually save the content to disk. And then you would need to populate the second field per row with this content as well.

As I said, the alternative would be a custom structure field that you would need to develop.

There is definitely no out of the box way to achieve what you want to do.

Alright, but what if we put aside the table and structure field and that I focus on the fact that I would like to show, on a project page, the articles in the same category as the one selected for the project ?

That would be possible for example with an info field and a custom query that returns a list.

Again, this field would not react on the fly when you select the category, but only after you actually save.

      ailleurs:
        label: "{{page.category}}"
        type: pages
        parent: site.find("projets").children.filterBy('category', {{page.category}})

something like that, right ?

That doesn’t make sense, because this is a select field that does not display anything unless you actually select the pages or populate the field via a hook or so.

Maybe we have a misunderstanding here. I’m still not sure why you would want to display all pages with that category. If you want to select from that set, then yes, that would work.

I’m using pages wrong here then I guess… I would like to show a list of all the projects with the same category.
Here is my blueprint :

sections:
  content:
    type: fields
    fields:
      category:
        label: Categorie
        type: select
        options:
          type: query
          query: site.structure.toStructure
          text: "{{ item.action }}"
          value: "{{ item.action }}"
      ailleurs:
        label: "{{ page.category }}"
        type: pages
        parent: # the list

What I mean is something like this:

ailleurs:
        label: "Other pages with category {{ page.category }}"
        type: info
        theme: none
        text: "{{page.siblings.filterBy('category', page.category).__toString}}"

Only instead of this text query you would create a custom page method that displays the data in a nice list. If that is what you want.

That’s working, yeah, but I thought that page would return me a list of the pages, clickable. (Like related in the template for example)

That’s what you would have to do in your custom page method.

For example

 public function getListOfSiblingsWithCategory(): string
    {
        $html = '<ul>';

        foreach ($this->siblings(false)->filterBy('category', $this->category()) as $page) {
            $html .= '<li>' . Html::a($page->url(), $page->title()) . '</li>';
        }
        $html .= '</ul>';
        return $html;
    }
 ailleurs:
        label: "Other pages with category {{ page.category }}"
        type: info
        theme: none
        text: "{< page.getListOfSiblingsWithCategory() >}"

Alright! I’m starting to understand! haha. Thank you.
I thought it would have been possible to show a page without formatting an info field but just by using a pages one.
Since custom page methods are pretty new to me, I checked the doc, but you code doesn’t seem to belong in /plugins/page-methods/index.php right?

Sorry, I quickly tested my code for possible errors in a page model, as a custom page method, it would have to look a bit different:

Kirby::plugin('my/page-methods', [
    'pageMethods' => [
        'getListOfSiblingsWithCategory' => function () {
            $html = '<ul>';

            foreach ($this->siblings(false)->filterBy('category', $this->category()) as $page) {
                 $html .= '<li>' . Html::a($page->url(), $page->title()) . '</li>';
            }
            $html .= '</ul>';
        
            return $html;
        }
    ]
]);

A pages field is a specialized (multi)select field. Like a select field, it gives you options from which you can select pages, only the selected ones are then stored in the content file and shown in the list.

An alternative to using the info field could be the pagesdisplay section plugin:

https://getkirby.com/plugins/rasteiner/pagesdisplay

Note that this is not a field, but a section.

That’s true, yeah, but when I create sections, I seem to be able to fetch the project list for example using section

  project: sections/projets

then projets.yml

type: pages
label: Projets
layout: cards
parent: kirby.page("projets")
template: projet
template: projet
size: tiny
text: "*{{ page.title }}* {{ page.category }}"

returns a list of these project without me needing to add them.

That’s true, but a standard section doesn’t allow queries. Therefore I posted the link to the plugin above which would let you do that.

Thanks for the plugin!