Site search gets dramatically better to use just by tidying up two things: the form and the results page. Start with the smallest thing that works.
<?php get_search_form(); ?>That outputs the standard form. To change how it looks, create searchform.php in your theme and its contents are used instead.
Building your own search form
<form role="search" method="get" class="search-form" action="<?php echo esc_url(home_url('/')); ?>">
<label>
<span class="sr-only">Search this site</span>
<input type="search" name="s" value="<?php echo esc_attr(get_search_query()); ?>"
placeholder="Enter a keyword" required>
</label>
<button type="submit">Search</button>
</form>Three things are required.
method="get"actionpointing athome_url('/')- An input whose
nameiss
With those three in place, the rest of the markup is up to you. Putting get_search_query() in value means the keyword stays in the box after searching, which is friendlier.
The search results page (search.php)
<?php get_header(); ?>
<main class="section">
<h1>Search results for "<?php echo esc_html(get_search_query()); ?>"</h1>
<?php if (have_posts()) : ?>
<?php global $wp_query; ?>
<p class="result-count"><?php echo esc_html(number_format($wp_query->found_posts)); ?> results found</p>
<ul class="search-results">
<?php while (have_posts()) : the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('thumbnail'); ?>
<?php endif; ?>
<h2><?php the_title(); ?></h2>
<p><?php echo esc_html(wp_trim_words(get_the_excerpt(), 80, '…')); ?></p>
</a>
</li>
<?php endwhile; ?>
</ul>
<?php the_posts_pagination(['prev_text' => 'Previous', 'next_text' => 'Next']); ?>
<?php else : ?>
<p>No articles matched "<?php echo esc_html(get_search_query()); ?>".</p>
<p>Shortening the keyword or trying different wording often helps.</p>
<?php get_search_form(); ?>
<?php endif; ?>
</main>
<?php get_footer(); ?>Always prepare guidance for the zero-result case. Rather than stopping at “nothing found,” it’s kind to offer a form to search again or a path to popular articles.
TipsHow to add pagination in WordPressHow to add paginationTipsChanging excerpt length and the \"read more\" textHow to adjust excerpt lengthRestricting what’s searched (excluding static pages and attachments)
By default, every publicly queryable post type is searched together. To limit it to posts and products, specify it with pre_get_posts.
function my_search_filter($query) {
if (is_admin() || !$query->is_main_query() || !$query->is_search()) {
return;
}
$query->set('post_type', ['post', 'shohin']);
$query->set('posts_per_page', 20);
}
add_action('pre_get_posts', 'my_search_filter');The is_admin() and is_main_query() guards are required. Without them you drag in admin-screen searches and sub-loops.
You can also switch the post type from the form side.
<input type="hidden" name="post_type" value="shohin">Include that in a search form on product pages and it searches products only.
A search form that filters by category or taxonomy
<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
<input type="search" name="s" value="<?php echo esc_attr(get_search_query()); ?>">
<select name="season">
<option value="">Choose a season</option>
<?php foreach (get_terms(['taxonomy' => 'season', 'hide_empty' => false]) as $term) : ?>
<option value="<?php echo esc_attr($term->slug); ?>"
<?php selected(get_query_var('season'), $term->slug); ?>>
<?php echo esc_html($term->name); ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit">Search</button>
</form>If the taxonomy’s query_var is enabled, a URL like ?s=…&season=winter filters automatically. selected() is a handy WordPress function that restores the chosen option.
When you want custom fields searched too
WordPress’s standard search covers titles and post content (and excerpts) only. Custom field values aren’t searched.
- Turn them into taxonomies—information used for filtering becomes more findable as a classification
- Use a search-extending plugin—some cover custom fields and even text inside PDFs
- Extend it with the
posts_searchfilter—this means editing SQL, so it’s advanced
The most reliable move is a design one: “put the information you want found into the post content or a taxonomy.”
TipsHow to create custom taxonomies (register_taxonomy)Designing your filtering axes as taxonomiesMaking search result URLs prettier
If you’d rather have /search/keyword/ than ?s=keyword, you can convert it with a redirect.
add_action('template_redirect', function () {
if (is_search() && !empty($_GET['s'])) {
$url = home_url('/search/' . urlencode(get_query_var('s')) . '/');
if (untrailingslashit($_SERVER['REQUEST_URI']) !== untrailingslashit(wp_make_link_relative($url))) {
wp_safe_redirect($url, 301);
exit;
}
}
});It looks tidier, but it isn’t required. Search result pages are usually designed not to be indexed by search engines, so it’s fine to treat this as low priority.
Summary
- Put the form in
searchform.phpandget_search_form()uses it.name="s"is required - The results page is
search.php. Always prepare guidance for zero results plus a form to search again - Restrict what’s searched by setting
post_typeviapre_get_posts(don’t forget the guards) - Standard search covers titles and content only. Put anything you want to filter by into a taxonomy
A site with working search behaves completely differently once the articles pile up.