Search Hooks
Control how CelerSearch intercepts and processes WordPress search queries.
Query Interception
celersearch_should_intercept_query
Control whether CelerSearch handles a specific query.
add_filter('celersearch_should_intercept_query', function($should_intercept, $query) {
// Don't intercept admin AJAX searches
if (wp_doing_ajax() && is_admin()) {
return false;
}
// Don't intercept queries with custom parameter
if ($query->get('use_native_search')) {
return false;
}
return $should_intercept;
}, 10, 2);
| Parameter | Type | Description |
|---|---|---|
$should_intercept | bool | Default interception decision |
$query | WP_Query | The WordPress query object |
Context Detection
celersearch_admin_area_type
Customize admin search area type detection.
add_filter('celersearch_admin_area_type', function($area_type, $query, $post_type) {
// Custom admin area for specific post type
if ($post_type === 'my_custom_type') {
return 'admin_my_custom_search';
}
return $area_type;
}, 10, 3);
celersearch_area_type
Determine search area type for custom contexts.
add_filter('celersearch_area_type', function($area_type, $query) {
// BuddyPress members directory
if (function_exists('bp_is_members_directory') && bp_is_members_directory()) {
return 'buddypress_members_search';
}
// bbPress forums
if (function_exists('is_bbpress') && is_bbpress()) {
return 'bbpress_forum_search';
}
return $area_type;
}, 10, 2);
celersearch_browse_area_types
Customize which area types are considered "browse" areas (areas that don't require a search term).
add_filter('celersearch_browse_area_types', function($browse_areas) {
// Add a custom browse area type
$browse_areas[] = 'my_custom_browse';
return $browse_areas;
});
| Parameter | Type | Description |
|---|---|---|
$browse_areas | array | Area type strings. Default: ['woocommerce_shop_browse'] |
Browse areas allow CelerSearch to intercept queries even without a search term, enabling features like faceted browsing on shop/archive pages.
Index Selection
celersearch_select_index
Programmatically select which index to use.
add_filter('celersearch_select_index', function($index, $query) {
// Use products index for shop pages
if (function_exists('is_shop') && is_shop()) {
return get_products_index(); // Your helper function
}
// Use different index for logged-in users
if (is_user_logged_in()) {
return get_members_index();
}
return $index;
}, 10, 2);
| Parameter | Type | Description |
|---|---|---|
$index | BaseIndex|null | Currently selected index |
$query | WP_Query | The WordPress query |
Priority order:
- Explicit WP_Query parameters (
celersearch_index) - Search area configuration
- This filter
- Default index from settings
Search Parameters
celersearch_search_params
Modify parameters before search execution.
add_filter('celersearch_search_params', function($params, $query, $index) {
// Add custom sorting
$params['sort'] = ['is_featured:desc', 'created_at:desc'];
// Add custom filter
if (!is_user_logged_in()) {
$params['filter'] = 'visibility = "public"';
}
// Increase results limit
$params['limit'] = 50;
return $params;
}, 10, 3);
| Parameter | Type | Description |
|---|---|---|
$params | array | Search parameters |
$query | WP_Query | The WordPress query |
$index | BaseIndex | The index being searched |
Available parameters:
q- Search query stringlimit- Max resultsoffset- Pagination offsetfilter- Filter string (syntax depends on provider)sort- Array of sort ruleshighlighting- Highlighting configuration
Sorting
celersearch_sort_options
Filter the map of sort keys to engine sort rules. This runs in BaseIndex::resolve_sort(), so it applies to every index and every path that resolves a sort key — search area default sorts, view sorting (?sort= in the views REST API), and custom callers.
add_filter('celersearch_sort_options', function($sort_map, $sort_key, $index) {
// Add popularity sort (products)
$sort_map['popularity'] = ['total_sales:desc'];
// Add price sorting
$sort_map['price'] = ['price:asc'];
$sort_map['price-desc'] = ['price:desc'];
return $sort_map;
}, 10, 3);
| Parameter | Type | Description |
|---|---|---|
$sort_map | array | Sort key => sort rules mapping |
$sort_key | string | The requested sort key |
$index | BaseIndex | The index resolving the sort |
Default sort options (field names come from the index's sort field map):
| Key | Posts index | Products index |
|---|---|---|
date | ['created_at:desc'] | ['post_date:desc'] |
date-asc | ['created_at:asc'] | ['post_date:asc'] |
title | ['title:asc'] | ['post_title:asc'] |
title-desc | ['title:desc'] | ['post_title:desc'] |
Unknown sort keys resolve to an empty array (relevance order).
Search Results
celersearch_search_results
Modify results after search execution.
add_filter('celersearch_search_results', function($results, $query, $index) {
// Add extra data to each hit
foreach ($results['hits'] as &$hit) {
$post_id = $hit['post_id'] ?? null;
if ($post_id) {
$hit['view_count'] = (int) get_post_meta($post_id, 'views', true);
$hit['is_bookmarked'] = user_has_bookmarked($post_id);
}
}
// Log search for analytics
log_search_query($query->get('s'), count($results['hits']));
return $results;
}, 10, 3);
| Parameter | Type | Description |
|---|---|---|
$results | array | Search results from search engine |
$query | WP_Query | The WordPress query |
$index | BaseIndex | The index searched |
Results structure:
[
'hits' => [...],
'estimatedTotalHits' => 150,
'processingTimeMs' => 5,
]
Pinned Searches
celersearch_apply_pinning
Control whether pinned (curated) search results are applied for a query. When the query exactly matches a pinned search label/alias, the curated, ordered set replaces engine results; contains-match keywords boost curated documents on top of engine results. Pinning is storefront-facing, so by default it is applied outside admin areas and skipped in admin.
add_filter('celersearch_apply_pinning', function($apply, $query, $area_type) {
// Disable pinning for editors previewing real relevance
if (current_user_can('edit_posts')) {
return false;
}
return $apply;
}, 10, 3);
| Parameter | Type | Description |
|---|---|---|
$apply | bool | Whether to apply pinning (default: true outside admin areas, false in admin) |
$query | WP_Query | The WordPress query |
$area_type | string|null | The detected search area type |
celersearch_pinned_search_max_records
Filter the maximum number of records that can be pinned to a single pinned search in the admin UI.
add_filter('celersearch_pinned_search_max_records', function($max) {
return 200; // Default: 100
});
| Parameter | Type | Description |
|---|---|---|
$max | int | Maximum pinned records per search (default: 100) |
Values of 0 or less fall back to the default. The cap exists because the curated set is fetched per-document at search time and a curated list isn't meaningfully paginated.
View Result Formatting
celersearch_view_search_hit
Customize individual search hit data before rendering in a view.
This is the view equivalent of celersearch_autocomplete_hit. Use it to add, modify, or remove fields on each hit before the view template displays it.
add_filter('celersearch_view_search_hit', function($hit, $raw_hit, $post, $view) {
// Add price for WooCommerce products
if ($post->post_type === 'product') {
$product = wc_get_product($post);
$hit['price'] = $product->get_price_html();
$hit['in_stock'] = $product->is_in_stock();
$hit['rating'] = $product->get_average_rating();
}
// Add custom thumbnail size
$hit['thumbnail'] = get_the_post_thumbnail_url($post, 'medium');
// Add reading time for blog posts
if ($post->post_type === 'post') {
$word_count = str_word_count(wp_strip_all_tags($post->post_content));
$hit['read_time'] = ceil($word_count / 200) . ' min read';
}
return $hit;
}, 10, 4);
| Parameter | Type | Description |
|---|---|---|
$hit | array | Formatted hit data for the view |
$raw_hit | array | Raw hit from the search engine |
$post | WP_Post | The WordPress post object |
$view | View | The view being rendered |
Default hit structure:
[
'id' => 123,
'title' => 'Post Title',
'url' => 'https://example.com/post-title',
'excerpt' => 'Short description...',
'type' => 'post',
'thumbnail' => 'https://example.com/image.jpg',
'date' => '2024-01-15',
'author' => 'John Doe',
]
Example: Conditionally modify hits per view
add_filter('celersearch_view_search_hit', function($hit, $raw_hit, $post, $view) {
// Only modify hits in the "products" view
if ($view->slug !== 'products') {
return $hit;
}
// Add stock badge
$product = wc_get_product($post);
$hit['badge'] = $product->is_in_stock() ? 'In Stock' : 'Out of Stock';
$hit['badge_class'] = $product->is_in_stock() ? 'badge-success' : 'badge-danger';
return $hit;
}, 10, 4);
Post Status Filtering
celersearch_search_statuses
Control which post statuses appear in results.
add_filter('celersearch_search_statuses', function($statuses, $query, $area_type) {
// Admins see all statuses
if (current_user_can('edit_others_posts')) {
return ['publish', 'draft', 'pending', 'private', 'future'];
}
// Authors see their own drafts
if (is_user_logged_in()) {
return ['publish', 'private'];
}
// Public only sees published
return ['publish'];
}, 10, 3);
Taxonomy Filtering
celersearch_unfilterable_taxonomies
Filter the taxonomies that are skipped when translating a WP_Query tax_query into engine filters. These taxonomies aren't stored as filterable facets in the index, so their clauses must be dropped rather than sent to the engine — which would otherwise reject the filter.
add_filter('celersearch_unfilterable_taxonomies', function($taxonomies, $query) {
// A private taxonomy that is never indexed
$taxonomies[] = 'internal_flags';
return $taxonomies;
}, 10, 2);
| Parameter | Type | Description |
|---|---|---|
$taxonomies | string | Taxonomies to skip. Default: ['product_visibility', 'product_shipping_class'] (WooCommerce internals — the products index skips these at index time too) |
$query | WP_Query|null | The WordPress query being translated |
Highlighting
celersearch_highlighting_enabled
Enable or disable search result highlighting.
// Disable highlighting globally
add_filter('celersearch_highlighting_enabled', '__return_false');
// Conditional highlighting
add_filter('celersearch_highlighting_enabled', function($enabled) {
// Disable for AJAX requests
return !wp_doing_ajax();
});
celersearch_highlighting_enable_bundled_styles
Control bundled highlighting CSS.
// Disable bundled styles (use your own)
add_filter('celersearch_highlighting_enable_bundled_styles', '__return_false');
Then add your own styles:
.celersearch-highlight {
background-color: #ffeb3b;
font-weight: bold;
padding: 0 2px;
}
Complete Example
Combine multiple hooks for a complete customization:
// 1. Control interception
add_filter('celersearch_should_intercept_query', function($intercept, $query) {
// Only intercept main queries with search term
return $intercept && $query->is_main_query() && $query->get('s');
}, 10, 2);
// 2. Select appropriate index
add_filter('celersearch_select_index', function($index, $query) {
$post_type = $query->get('post_type');
if ($post_type === 'product') {
return get_index_by_slug('products');
}
return $index;
}, 10, 2);
// 3. Customize search params
add_filter('celersearch_search_params', function($params, $query, $index) {
// Boost recent content
$params['sort'] = ['_rankingScore:desc', 'created_at:desc'];
// Filter by category if set
if ($cat = $query->get('cat')) {
$params['filter'] = "taxonomies.category.id = {$cat}";
}
return $params;
}, 10, 3);
// 4. Enhance results
add_filter('celersearch_search_results', function($results, $query, $index) {
// Track search
track_search($query->get('s'), count($results['hits']));
return $results;
}, 10, 3);