To search a WordPress custom post type and let visitors narrow results, build a GET form and pass its validated values into a WP_Query. Set post_type explicitly; use s for keywords, tax_query for taxonomy terms, and meta_query for custom fields. For a few fixed filters, custom code is often straightforward. For many facets or editor-managed controls, a plugin may be a better fit.
Choose how to build the search
A small custom form and query work well when you know which fields visitors need and can maintain the code. A plugin is worth considering when filters are numerous, need richer controls, or should be managed by editors.
As an Amazon Associate I earn from qualifying purchases.
- Custom code: You control the form, validation, query, and results template. Someone must maintain those pieces as the site changes.
- Plugin: A plugin can expose configurable filters, but compatibility depends on the site’s theme, listing query, and setup. Check current features, maintenance, licensing, and price before choosing.
Build a GET form for a results page
Use a stable page or archive as the form’s destination. GET submissions put filter selections in the URL, making searches easier to bookmark and share. Keep parameter names predictable and decide which filters visitors actually need.
For example, a form might submit a keyword as q and a genre selection as genre. The names should correspond to the parameters your handler reads; they do not need to match WordPress query argument names.
#1 Best Overall
Read and validate submitted filters
Do not let visitor input choose an arbitrary post type, metadata key, or query structure. Set those in server-side code. Sanitize text, and validate selections against the registered taxonomy and its terms before using them. For numeric filters, use a numeric validator and enforce an allowed range.
This illustrative handler searches published items in a post type called book, optionally matching a keyword and a genre term:
Rank #2
<?php
$search = isset( $_GET['q'] )
? sanitize_text_field( wp_unslash( $_GET['q'] ) )
: '';
$genre = isset( $_GET['genre'] )
? sanitize_key( wp_unslash( $_GET['genre'] ) )
: '';
$args = array(
'post_type' => 'book', // Replace with the registered post type slug.
'post_status' => 'publish',
'posts_per_page' => 10,
);
if ( '' !== $search ) {
$args['s'] = $search;
}
if ( '' !== $genre ) {
// Validate that this slug belongs to the registered taxonomy before querying.
$args['tax_query'] = array(
array(
'taxonomy' => 'genre', // Replace with the registered taxonomy slug.
'field' => 'slug',
'terms' => $genre,
),
);
}
$query = new WP_Query( $args );
Replace the example slugs with the site’s registered values. The example is a teaching pattern, not a tested drop-in plugin; term validation is an essential part of adapting it. WordPress documents the relevant WP_Query arguments and structures.
Add taxonomy and custom-field filters deliberately
Use tax_query when filtering by terms in a taxonomy, and meta_query for custom-field values. Both use nested arrays. When there are multiple clauses, choose whether all conditions must match (AND) or any may match (OR); do not leave the relationship implicit in your design. Build clauses only for validated, non-empty selections.
Rank #3
Before adding a metadata filter, establish the field’s data type and stored value format. For numeric ranges, use numeric comparison settings so values are compared as numbers rather than strings. Keep supported metadata keys and comparison options fixed in server-side configuration.
Render results safely and preserve filters
Render the loop using the site’s existing template conventions. Escape values for the output context, including attributes and visible content. WordPress’s get_search_query() returns the search query escaped for an HTML attribute by default, and esc_attr() is available for attribute values. Apply the appropriate escaping to selected options, input values, and result content.
Rank #4
If you add pagination, carry the active filter values into the pagination links and use the correct page variable for the page context. Test that the results and selected controls remain consistent as visitors move between pages.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsUse a custom query or modify the main query?
A dedicated results template can run its own WP_Query, giving you direct control over the post type and filters. If you instead modify the global main query, scope changes carefully with pre_get_posts so the intended front-end query is affected and other queries are not. Registering a custom post type alone does not add it to the main query, as the WordPress Plugin Handbook explains.
Best Value
When a plugin may be a better fit
Search & Filter describes filtering by post type, custom taxonomy, post date, custom fields, and other dimensions. Its listing identifies AJAX results and additional custom-field controls as Pro features. Confirm the current edition, compatibility, support, and licensing details before relying on a specific capability.
FacetWP documentation covers taxonomy facets, and its custom post type guidance says searchable custom post types can be filtered. FacetWP filters a FacetWP-enabled listing query, so the site’s query and template integration matter.
Compare options against the actual site: how many filters are needed, whether editors must change them without developer help, who will maintain the setup, whether the theme or page builder supports the results query, and whether page reloads are sufficient or richer interactions are needed. Verify current pricing and licensing directly before purchase.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchExpose search through the REST API when needed
For a JavaScript-driven interface, a custom post type can use WordPress’s default REST collection routes when it is registered with show_in_rest => true. By default, these routes use the wp/v2 namespace. If the default collection behavior cannot express the required filters, use a custom route or controller. See the WordPress REST API documentation for custom content types.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




