How to search by custom meta keys in WordPress

A couple of sites we've been developing recently have required us to create custom post types with meta keys, and then create a search of the values stored in the meta keys. Here's how we achieved it. The code used in this example was written for use with the plugin Job Manager, allowing you to search on vacancies.

Create a custom search form

The first step is to create your own custom search form to bypass the standard wordpress search. This function goes into function.php and then can be called by whatever page you want the form to appear on.

function custom_search_form(){
?>

    <form id="searchform" action="http://penny.ekouk.com/searchresults/" method="get">
    <label>Job description:</label> <input id="description" type="text" name="description" value="" />

     <label>Salary:</label> <select name="salary"> 
                              <option value="">Any</option></select>
                              <option value="15000">15k +</option>
                              <option value="20000">£20k +</option>
                              <option value="30000">£30k +</option>
                              <option value="40000">£40k +</option>
                              <option value="50000">£50k +</option>
                              <option value="60000">£60k +</option>
                              <option value="70000">£70k +</option>
                              <option value="80000">£80k +</option>
                              <option value="90000">£90k +</option>
                              <option value="100000">£100k +</option>
                            </select>
 
     <label>Location:</label> <select name="region"> 
                                <option value="">Anywhere</option>
                                <option value="east">East</option>
                                <option value="south">South</option>
                                <option value="west">West</option>
                                <option value="north">North</option>
                               </select>

     <input id="searchsubmit" type="submit" value="Search" />

   </form>
<?php
}

Create your results page

Next you need to create the page that will process the submission of the form, and display the search results.

$region = $_GET[&#039;region&#039;];
$salary = $_GET[&#039;salary&#039;];
$description = $_GET[&#039;description&#039;];
$searched_posts = meta_key_search($region, $salary, $description);
while($searched_posts->have_posts()) : $searched_posts->the_post();
   jobman_display_job_search($post->ID);
endwhile;

This gets the search terms passed into the page via the URL, and then uses two functions to process them. The first function performs the search query, the second works with search results and outputs them in a useful way.

The search function

Add this to functions.php

function meta_key_search($region, $salary, $description){
global $wpdb;
$args = array(
          &#039;post_type&#039; => &#039;jobman_job&#039;,
          &#039;orderby&#039; => &#039;meta_value_num&#039;,
          &#039;order&#039; => &#039;ASC&#039;,
          &#039;meta_query&#039; => array(
               array(
                  //data4 is location 
                  &#039;key&#039; => &#039;data4&#039;,
                  &#039;value&#039; => $region,
                  &#039;compare&#039; => &#039;LIKE&#039;,
                ),
               array(
                  //data1 is salary
                  &#039;key&#039; => &#039;data1&#039;,
                  &#039;value&#039; => array($salary, 99999999),
                  &#039;compare&#039; => &#039;BETWEEN&#039;,
               ),
               array(
                  //data5 is description
                  &#039;key&#039; => &#039;data5&#039;,
                  &#039;value&#039; => $description,
                  &#039;compare&#039; => &#039;LIKE&#039;,
               )
           ),
          &#039;sentance&#039; => true, 
           );

$searched_posts = new WP_Query($args);

echo "<br>Total results: ";
echo $total_results = $searched_posts->found_posts;
echo "<br><br>";

return $searched_posts;
}

The 'post_type' is the name of your custom post type, for Job Manager this is 'jobman_job'. The Meta Query is where the search on meta values happens. Use the meta key, the value you're looking for, and how you want to compare the query with the stored data. The final line 'sentance'=>true, allows the query to search for phrases in the database. Without this line it will only search for exact matches. Sentance isn't a typo (by me anyway), it's in the core wordpress code.

Processing the results

This code is probably more complicated than most custom post types will need because it's been built to work with the existing Job Manager plugin. If all you want to do is list the post title in your results you don't even need this function. This is for putting content from the meta keys into the results page.

function jobman_display_job_search($job) {

global $jobman_shortcode_job, $jobman_shortcodes, $jobman_field_shortcodes;
$options = get_option( &#039;jobman_options&#039; );
$content = &#039;&#039;;

if( is_string( $job ) || is_int( $job ) ) 
    $job = get_post( $job );

if( $options[&#039;user_registration&#039;] && $options[&#039;loginform_job&#039;] )
    $content .= jobman_display_login();

if( NULL != $job ) {
     $jobmeta = get_post_custom( $job->ID );
     $jobdata = array();
     foreach( $jobmeta as $key =>; $value ) {
         if( is_array( $value ) ) 
             $jobdata[$key] = $value[0];
         else 
             $jobdata[$key] = $value;
      }
}

// Check that the job hasn&#039;t expired
if( array_key_exists( &#039;displayenddate&#039;, $jobdata ) && &#039;&#039; != $jobdata[&#039;displayenddate&#039;] && strtotime($jobdata[&#039;displayenddate&#039;]) <= time() )
    $job = NULL;

// Check that the job isn&#039;t in the future
if( strtotime( $job->post_date ) > time() )
    $job = NULL;

if( NULL == $job ) {
    $page = get_post( $options[&#039;main_page&#039;] );  
    $page->post_type = &#039;jobman_job&#039;;
    $page->post_title = __( &#039;This job doesn&#039;t exist&#039;, &#039;jobman&#039; );

    $content .= &#039;<p>&#039; . sprintf( __( &#039;Perhaps you followed an out-of-date link? Please check out the jobs we have currently available.&#039;, &#039;jobman&#039; ), get_page_link( $options[&#039;main_page&#039;] ) ) . &#039;</p>&#039;;

    $page->post_content = $content;

    return array( $page );
}

$template = $options[&#039;templates&#039;][&#039;job_list&#039;];
jobman_add_shortcodes( $jobman_shortcodes );
jobman_add_field_shortcodes( $jobman_field_shortcodes );
$jobman_shortcode_job = $job;
$content .= do_shortcode( $template );
jobman_remove_shortcodes( array_merge( $jobman_shortcodes, $jobman_field_shortcodes ) );
$page = $job;
$page->post_title = $options[&#039;text&#039;][&#039;job_title_prefix&#039;] . $job->post_title;
$page->post_content = $content;
echo $page->post_content;

return array( $page );

}

This retrieves the meta keys and then uses the existing job list template to show the results. If you are not using Job Manager, this is the part of the function that should help you to retrieve the meta values.

$jobmeta = get_post_custom( $job->ID );

$jobdata = array();
foreach( $jobmeta as $key => $value ) {
    if( is_array( $value ) ){
        $jobdata[$key] = $value[0];
    } else {
        $jobdata[$key] = $value;
    }<div style="display: none">writing paper</div>
}
zp8497586rq

Be Sociable, Share!

The following two tabs change content below.

james

Latest posts by james (see all)

Comments are closed.

Scroll to Top