I’m wondering, with the actual Kirby 3.9.x, is it possible in the panel to constrain a search? Like if I want to search for “Colombie”, Kirby is proposing “Colombier” as well but I want to contrain the search to “Colombie” only. Possible?
In the frontend, you would limit the search to whole words, to achieve the same, you should could adapt the page view search in a plugin.
No, I mean the search in the backend. The one available when in the blueprint this option is set:
search: true
Is it possible to used “” in order to force to search a whole word only?
Maybe it did not express myself well.
Kirby has an option to limit search to whole words in the search components, which you can use when you do a front-end search.
In the pages search in the Panel, however, this option is not used and it is not configurable via the blueprint. This is the code from /kirby/config/areas/site/searches.php
$pages = $kirby->site()
->index(true)
->search($query)
->filter('isListable', true)
->paginate($limit, $page);
The only way to change this is by changing the Panel search:
Hi, I’m working with @nicolasbulb on this project, and here is what I tried, with no success.
I have this working custom search method site/plugins/search-method/index.php
and I’m trying to use it inside a Panel search area plugin to only search for full words.
<?php
/**
* Fork of the native $pages->search() method
* Only searches for full matches
*/
function search($collection, $query, $params = array()) {
if(is_string($params)) {
$params = array('fields' => str::split($params, '|'));
}
$defaults = array(
'minlength' => 2,
'fields' => ['title','tags','architect','photographer','publisher','city','country','place','state'],
'words' => true,
'score' => array()
);
$options = array_merge($defaults, $params);
if(empty($query)) return $collection->limit(0);
$results = $collection->filter(function($page) use($query, $options) {
$data = $page->content()->toArray();
$keys = array_keys($data);
if(!empty($options['fields'])) {
$keys = array_intersect($keys, $options['fields']);
}
$page->searchHits = 0;
$page->searchScore = 0;
foreach($keys as $key) {
$score = a::get($options['score'], $key, 1);
// check for full matches
if($matches = preg_match_all('!' . preg_quote($query) . '!i', $data[$key], $r)) {
$page->searchHits += $matches;
$page->searchScore += $matches * $score;
}
}
return $page->searchHits > 0 ? true : false;
});
$results = $results->sortBy('searchScore', SORT_DESC);
return $results;
}
Here is my Panel search area plugin but it doesn’t work as expected, and I don’t understand why.
site/plugins/search/index.php
:
<?php
Kirby::plugin('timotheegoguely/search', [
'areas' => [
// extending the core search
'site' => function ($kirby) {
return [
'searches' => [
'pages' => [
'query' => function (string $query, int $limit = 12) use ($kirby) {
$collection = $kirby->site()
->index(true)
->filter('isReadable', true);
$results = [];
// I use the custom search method here
$pages = search($collection, $query)->limit($limit);
foreach ($pages as $page) {
$results[] = [
'image' => $page->panel()->image(),
'text' => Escape::html($page->title()->value()),
'link' => $page->panel()->url(),
'info' => Escape::html($page->id())
];
}
// But I didn't get any results....
return $results;
}
]
]
];
},
]
]);
What am I doing wrong?
One thing is certainly that your returned array does not contain the results
key. Also, it seems that you have to initialize the $kirby variable inside the function, and remove the $kirby parameter from 'site' => function ($kirby) {
.
I would then try if it works if your search function just returns the collection as is. Take a look at the native kirby code as well.