WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm aware that there is a plugin that will do this, but it is too broad for what I would like to add.

Below is my first attempt at expanding the search to query custom fields, but it's returning nothing. I've written code in the past to create queries, but this is my first time trying to modify a pre-existing one and I'm clearly missing something.

function st_search_all( $query ) {
    if ( $query->is_search ) {

        $query->set( 'post_type', array( 'page', 'attachment', 'post' ) );
        $query->set( 'post_status', 'inherit' );
        $query->set( 'meta_query', array(
                    'key'       => '_st_plaintext',
                    'value'     => "%{$query->get('s')}%",
                    'compare'   => 'LIKE'
                    'key'       => 'Training Classes',
                    'value'     => "%{$query->get('s')}%",
                    'compare'   => 'LIKE'
                    'key'       => 'External Content',
                    'value'     => "%{$query->get('s')}%",
                    'compare'   => 'LIKE'
    return $query;
add_filter( 'pre_get_posts', 'st_search_all' );

The other thing is, I will need to include a search of the main content of pages/posts also, which this code doesn't attempt. What would that meta key be if I wanted to include it within the meta_query?

EDIT: Dumping the resulting query string after making @s_ha_dum's suggested changes (removing %s, adding the OR relationship, and removing the post type from the post_type) is returning the following (indention added). I'm not extremely familiar with SQL, but it appears that the query generated is requiring the title or content to match the query before it will even check any of the added fields. Am I misreading something? If not, how can I modify that through the WP API?

string(494) " 
  AND ((
        (dev_posts.post_title LIKE '%SBIR%') OR 
        (dev_posts.post_content LIKE '%SBIR%')
  )) AND 
    (dev_posts.post_password = '') AND 
    dev_posts.post_type IN 
    ('page', 'attachment') AND 
    (dev_posts.post_status = 'inherit') AND 
    ((dev_postmeta.meta_key = '_st_plaintext' AND 
      CAST(dev_postmeta.meta_value AS CHAR) LIKE '%SBIR%') OR 
      (mt1.meta_key = 'Training Classes' AND 
        CAST(mt1.meta_value AS CHAR) LIKE '%SBIR%') OR 
      (mt2.meta_key = 'External Content' AND 
        CAST(mt2.meta_value AS CHAR) LIKE '%SBIR%') )
share|improve this question
up vote 2 down vote accepted

Add this temporarily to your functions.php. It will break things but you can see the WHERE clause. Be sure to remove it because things won't work right if you leave it there.

function dump_where($w){

The first thing you should notice is that the % signs get escaped. Remove those and WordPress will add them back unescaped. If you only wanted one of those at the beginning or the end, but not both, this might be trickier. Luckily you don't.

Second, the default relationship appears to be AND so unless you want to enforce a match on every one of those meta_keys you should add a relationship to your meta query.

 $query->set( 'meta_query', array(
            'relation' => 'OR',
                'key'       => '_st_plaintext',
                /* and the rest of your query */

Third, post content is already searched.You shouldn't have to do anything to make that happen. Take a look at the WHERE clause my temporary code dumps and you should be able to see where that happens.


share|improve this answer
thanks for the suggestions. I've added the relation, removed the post value from the array and stripped the %s, but it still isn't returning what I would expect. I've edited the question to show the query being generated and what I think the issue is. Any additional suggestions? – Dan Jan 24 '13 at 2:19
I don't know what you expect the query to return. If you can tell what is or isn't matching maybe I can tell you something. – s_ha_dum Jan 24 '13 at 4:50
I would expect the query to return matches to any one of the fields, but it's only returning posts that have a matching (title OR subject) AND (any one of the other fields queried). This does not appear to be what is happening. – Dan Jan 24 '13 at 5:26
That is the way meta_query gets built. Looks like it is hard-coded but I may be wrong. That is a lot of code to digest. The only things I can think of is a regex replace of the AND (very tricky), or two queries. – s_ha_dum Jan 24 '13 at 14:53
Thanks. Knowing that helps a lot. Looks like this is less trivial that I'd hoped. – Dan Jan 24 '13 at 15:33

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.