Drivers And Logging
Search exposes a public frontend route and records first-party search behavior when logging is enabled. The search backend is behind Capell\Search\Contracts\Search.
Config Keys
Section titled “Config Keys”| Key | Use |
|---|---|
capell-search.enabled | Enables frontend search. |
capell-search.show_header_search | Registers the header search render hook. |
capell-search.driver | database or scout; defaults from CAPELL_SITE_SEARCH_DRIVER. |
capell-search.route_path | Public route path, default search. |
capell-search.results_per_page | Default pagination size. |
capell-search.excerpt_length | Generated excerpt length. |
capell-search.minimum_query_length | Rejects short queries. |
capell-search.record_search_logs | Writes query and click logs. |
capell-search.hash_visitor_data | Hashes visitor identifiers in logs. |
capell-search.database.* | Database driver table and column mapping. |
capell-search.scout.* | Scout model and column mapping. |
capell-search.logs.retention_days | Retention window for purge behavior. |
The database driver expects a flat searchable source. Do not point it at a table whose title, body, URL, or type values live only in nested JSON unless the configured columns can be queried directly. For standard Capell pages, use a flattened index table/view, bind a custom Search implementation, or switch to Scout.
Swap the Search Driver
Section titled “Swap the Search Driver”Bind the contract when a package needs a custom backend.
use Capell\Search\Contracts\Search;use Capell\Search\Data\SearchResultData;use Illuminate\Contracts\Pagination\LengthAwarePaginator;use Illuminate\Pagination\LengthAwarePaginator as Paginator;
final class DemoSearchDriver implements Search{ public function search(string $query, int $perPage = 10, int $page = 1): LengthAwarePaginator { $results = collect([ new SearchResultData( title: 'About Capell', url: '/about', excerpt: $this->highlight('About Capell CMS', $query), type: 'page', score: 1.0, ), ]);
return new Paginator($results, $results->count(), $perPage, $page); }
public function highlight(string $text, string $query): string { return str_ireplace($query, '<mark>' . e($query) . '</mark>', e($text)); }}
$this->app->singleton(Search::class, DemoSearchDriver::class);Escape text before adding markup. Search results are rendered on public pages.
Logging
Section titled “Logging”Use package actions instead of writing SearchLog rows directly:
RecordSearchActionRecordSearchResultClickActionPurgeSearchLogsAction
Hash visitor data unless a product requirement says otherwise.
Verification
Section titled “Verification”vendor/bin/pest packages/search/tests --configuration=phpunit.xml