Limit Panel Search to depth in sitetree

I want to limit the depth to which the panel search goes into the sitetree to value of 3 or something - is this possible?

Maybe you overwrite the core search-function with your own: https://getkirby.com/docs/reference/plugins/components/search

I think this will also be used in the panel then.

Short answer: no :frowning: .

Long Answer:
The search component is “only” responsible for returning results for a given collection and query. However it does not compose the collection to search through, that is done by the panel api.

Devtools tell me that the panel uses the /api/site/search endpoint. That is configured in kirby/config/api/routes/site.php, it looks like this:

[
    'pattern' => 'site/search',
    'method'  => 'GET|POST',
    'action'  => function () {
        $pages = $this
            ->site()
            ->index(true)
            ->filterBy('isReadable', true);

        if ($this->requestMethod() === 'GET') {
            return $pages->search($this->requestQuery('q'));
        } else {
            return $pages->query($this->requestBody());
        }
    }
],

The interesting part here is the call to ->index(true) - that makes it so that all pages (and drafts) are searched through. If we want to limit this search, we would need to replace the call to index with something else.

Unfortunately we can’t override api endpoints.
Making it work would therefore be rather hacky: one could conceivably think to override the Vue component in the panel to change what api endpoint is used.

Thanks for your replies, unfortunately none is really solving my problem. to illustrate the case a bit more:
i am using virtual pages coming from a mysql-db and have integrated creation & editing neatly in to the panel (kirby ftw - once more!). the site is an archive of a video-art festival, the relational structure is basically:

Festival -> Videos -> Artists

since custom page classes allow me to create children dynamically whereever i want (independent from a file- or relational structure) i aimed to make it easy for the editors to navigate the content. so when you look at an artist in the panel, you will see all his assiciated videos as children. if you look at a video, you see all the assiciated artists as children. nice for the editor, but for Kirby this creates a recursion in the site tree:

Artist -> Video -> Artist -> Video -> …

This causes the parser to run out of memory and the search in the panel to spin forever. So ideally, i would want to stop the parsing of the site tree at a depth of 3 to prevent the recursion.

Self made problem – i know – but maybe there’s a way to solve this with some Kirby-Magic as well?

I know this sounds self referential, but this is the first solution that comes to mind.

I’d suggest to remove the videos as children of the artists.
Just leave Festival -> Videos -> Artists

Instead, in the artist blueprint use a pagesdisplay section (plugin here: https://github.com/rasteiner/k3-pagesdisplay-section) to show his other videos with a query.

sections:
  othervideos:
    type: pagesdisplay
    query: site.index.filterBy("template", "video").filterBy("artist", page.id, ",")

Note that this query makes various assumptions, so it probably needs to be adjusted, but maybe it gets the idea across.

Was going to suggest the same!

1 Like

oh, that’s because you have the filesdisplay plugin :stuck_out_tongue:

1 Like

That sounds indeed like an interesting option, thanks!

Pages will be clickable i assume?
Can i also access the pages from within the template?

I just don’t get my head around the filter you’ve outlined. Since the artists are children of the video, do i retrieve videos who’s children are of a certain artist-page-id with this? (there is no property “artist” on the video, in fact those are many-to-many-relations).
Thanks again!

The many-to-many relationship has to be expressed in the db somehow. How that is exactly expressed depends on the type of database, but at “the core” they all work the same: the artist documents must have a list of foreign keys that map to videos, and the videos need to have a list of foreign keys that map to artists.

In my query example above the artist field would contain a list of artist ids, each separated by a comma.

But thinking about it, I didn’t see the most obvious solution, since you already have the “filter code” to get your videos of an artist: It’s your current children() method of your artist model. Therefore, just rename that children() function to videos(), change the parent to the correct festival page when calling Pages::factory, and then do this query:

query: page.videos

You can then do the same in your template :slight_smile: ($page->videos());

Yes, it’s the same UI as a normal pages section (it reuses the same template), but it disables the sorting and creation of pages (since those would be ambiguous for query results)

Ha, you are totally right! That sounds like a five-minute-fix now, awesome :boom:. I will try it out and let you know how it went!

Worked like a charm! Problem solved!
I do get very nice results now, e.g. if i search for a video i also find the artist and the festival among the results. Pretty neat!
Thanks a bunch @rasteiner !

1 Like