Focusing Search
Improving the built in search functionality of WordPress
By Flynn O’Connor / @thoronas
My name is Flynn O’Connor
•Developing WordPress themes for 4 years.•Lead developer at Forge and Smith•Slides available here: http://slidesha.re/VTYhJ4
The basic form<form method="get" id="searchform” action="<?php echo home_url( '/' ); ?>">
<div>
<label class="screen-reader-text" for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</div>
</form>
How WordPress Search work?
When you use the default WordPress search form it’s the equivalent of this:$query = new WP_Query( ’s’ => ‘keyword’ );
Take Control
Inputs added to the form can control the query. But they must match the corresponding query parameters.
Doing it wrong
Neither of these will work automatically:
•<input name="post-type" type="hidden" value=”listing" />
•<input name="postType" type="hidden" value=”listing" />
It’s like trying to do:
$query = new WP_Query( ’post-type’ => ‘listing' );
The Right Way•<input name="post_type" type="hidden" value=”listing" />
Equivalent of:$query = new WP_Query(
’s’ => ‘keyword’,
‘post_type’ => ‘listing’ );
The Search query is altered to only search events posts.
Give users control
Allow users to search within a single category with a WordPress core function. Example:
<?php wp_dropdown_categories(); ?>
Outputs:<select id="cat" name="cat">
<option value="1" class="level-0">Uncategorized</option>
<option value="4" class="level-0">Featured</option>
</select>
Expanding the choices<?php $search_taxonomy = get_terms( ’custom_taxonomy' );
if ( !empty( $search_categories ) ) {
foreach( $search_taxonomy as $term) {
echo ‘<label for=”term_’ . $term->term_id . ‘">
<input type="checkbox" name=”custom_tax[]”id=”term_' . $term->term_id . '" value="' . $term->term_id . ’”>' . $term->name . ‘</label>’;
}} ?>
The results
What your form looks like:
What your query string looks like
Form inputs are helpful for adding simple search parameters. But for multiple choice elements we need more control.The following won’t work:
$args = array (‘custom_tax’ => array(7, 8)
);$query = new WP_Query( $args );
Say hello to my little friend
pre_get_posts
This action will alter the query before it is run. With this you can do complicated search queries involving taxonomies and meta values.
function filter_search_terms (){if ( isset( $_GET['category'] ) ) {
global $wp_query;$categories = array_map( 'absint',
$_GET['category'] );
$tax_args = array (array(
'taxonomy' => 'category','field' => 'id','terms' => $categories
));$wp_query->set('tax_query', $tax_args);
}}
add_action('pre_get_posts','filter_search_terms');
Changing the structure
If you allow search for multiple post types sometimes you will need to have different structure/layout for your content.
get_post_type( )
Use this to load different templates based on the post types searched.
while ( have_posts() ) : the_post();
get_template_part( ’content', get_post_type() );
endwhile;
The elephant in the room
The major problem with the built in WordPress search: search results can’t be sorted by relevance to the search term.
You can sort the results :• Date• Name• Menu Order• Random
Relevanssi
Default search results ordered by relevance instead of date.
Non relevant search results
Relevant search results
Plays nice with others
Because we are using pre_get_posts and passing valid query variables via form elements all of our custom search queries will work with Relevanssi right out of the box.
Thanks for listening!
Questions/Comments?