Extend search with predefined search query strings

Almost every WordPress developer had some annoyance with the basic search functionality of WordPress. Today I customised the search functionality for one of my projects so I am able to add a list of comma separated search query strings to a post where I want it to be found on. So for example a product like “bicycle” needs to be found on “bike”.

To achieve this I first hooked into the SQL query of a search request trough the posts_join and posts_where functions.

Post meta table join

To use post meta data in combination with a post I had to make a connection between the two tables using a left join.

 * Modifies search query join clause
 * Adds a left join for post meta
function search_posts_join( $join ) {
   global $wp_query, $wpdb;
   // Searching and not in admin
   if ( ! is_admin() && $wp_query->is_search && isset( $wp_query->query_vars['s'] ) ) {
      $join .= "LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id";
   return $join;
add_action( 'posts_join', 'search_posts_join' );

Changing the where clause

Now the connection with the post meta table is made I am able to compare the value of the post meta field “search_queries” to the search query string. The where clause searches for similarities with the post title as well, so you have the chance on a match from both sides.

 * Modifies search query where clause
 * Changes the where clause so that it checks a pre defined search queries
 * stored in a meta value.
function search_posts_where( $where ) {
   global $wp_query, $wpdb;
   // Searching and not in admin
   if ( ! is_admin() && $wp_query->is_search && isset( $wp_query->query_vars['s'] ) ) {
      // Store search query
      $s = $wp_query->query_vars['s'];
      // Write the where clause from scratch
      // Check post title or comma seperated meta value with key 'search_queries'
      $where  = " AND (($wpdb->posts.post_title LIKE '%$s%') OR ($wpdb->postmeta.meta_key = 'search_queries' AND $wpdb->postmeta.meta_value LIKE '%$s%'))";
      // Only posts from 'products' post type
      $where .= " AND wp_posts.post_type = 'products'";
      // Published posts only
      $where .= " AND wp_posts.post_status = 'publish'";
      // Because of the join, otherwise multiple same results
      $where .= " GROUP BY $wpdb->posts.ID";
   return $where;
add_action( 'posts_where', 'search_posts_where' );

Add post meta field

I created a meta box with a large field to store the comma separated search query strings. In my case a added this metabox and field to my “products” custom post type.

// Adds search settings metabox
function add_search_metabox() {
   add_meta_box( 'search_settings_metabox', __( 'Search settings', 'theme' ), 'search_settings_metabox', 'theme' );
add_action( 'add_meta_boxes', 'add_search_metabox' );
// Adds search settings metabox fields
function search_settings_metabox( $post ) {
   $search_queries = ( get_post_meta( $post->ID, 'search_queries', true ) ) ? get_post_meta( $post->ID, 'search_queries', true ) : '';
   $html = '<table class="form-table">';
      $html .= '<tbody>';
         $html .= '<tr>';
            $html .= '<th scope="row">';
               $html .= '<label for="search_queries_field">' . __( 'Search queries', 'gtp_translate' ) . ':</label>';
            $html .= '</th>';
            $html .= '<td>';
               $html .= '<input type="text" name="search_queries" id="search_queries_field" class="large-text" value="' . $search_queries . '">';
               $html .= '<p class="description">' . __( 'Comma seperated strings to extend the matching search queries', 'gtp_translate' ) . '</p>';
            $html .= '</td>';
         $html .= '</tr>';
      $html .= '</tbody>';
   $html .= '</table>';
   echo $html;

Store search query strings

Last I needed to make the functionality to store the comma separated search query strings. I added little checkings on this save function. You can make this more extensive if you want.

// Saves search settings metabox fields
function save_search_settings_metabox( $post_id ) {
   if ( ! empty( $_POST['search_queries'] ) ) {
      update_post_meta( $post_id, 'search_queries', $_POST['search_queries'] );
add_action( 'save_post_products', 'save_search_settings_metabox' );
Robbert Vermeulen

Need help from a WordPress expert?

I would love to hear about your project and how I can help you achieve your goals