Search Form Based On Tutorial Not Working

Crystal Ball Programming and Why Your Searchbox Failed

Your form fails because of this:

action="<?php bloginfo('template_url'); ?>/MilkNHny/search.php"

You should never directly call a template via URL.

Your template assume the WordPress environment has been loaded, which is a fair assumption. However, because you called it directly, it has not.

Search.php is the template WordPress looks for when it does a search. It doesnt do the actual search. If we apply some logic, browser goes to search.php, and immediatley tries to display the results without:

  • bothering to actually perform the search
  • loading plugins and themes
  • checking rewrite rules
  • sanitising data

Since PHP has no crystal ball functionality, things error out. Sorry if it seems brutal, but the point needed demonstrating effectively.

Remember, a computer does as it’s told, not as it’s expected. If you can’t answer the question “Why would it do that?” or “how does it know?” then there’s a very, very good chance that it doesn’t know, and it doesn’t do that, and things are going to blow up spectacularly.

How a Search Request Works

When you go to a URL, WordPress looks up a big list of regular expressions and sees which is the first one that matches. These ‘regexes’ tell WordPress how to map /category/example-category/hello-world into something it can pass into WP_Query, e.g. name=hello-world. The parameters are identical to those used in WP_Query, which is where the post loop comes from.

One of these parameters is s. The search form passes in the search query via the URL e.g.:

example.com/?s=helloworld

WordPress then passes this s parameter into its main loop query, and makes a mental note:

“hey the s thing is there, this must be a search query! Does the theme have a search.php? LOAD THE SEARCH.PHP TEMPLATE!!!!!! ( ps: load index.php if we don’t )

So now WordPress goes off and somewhere there’s a WP_Query( array ( 's' => 'helloworld' ) ), and it’s all wrapped up so you can then print it out using have_posts etc

So The Basic Search Form is?

So now that we know how a search query works, lets see the basic markup:

<form method="GET" action="<?php echo home_url(); ?>">
    <input type="text" name="s">
</form>
  • method=”GET” because GET variables are passed in the URL, POST variables are passed in headers we don’t see in the address bar
  • home_url() because that’s the main index of the site. We could search within a category of a date archive by putting ?s= on the end of other pages, but lets assume we want to search the entire site
  • name="s" because this is the query var WordPress uses to specify a search string

We can expand this further using other functions such as get_search_query() etc, but those aren’t necessary.

A Bonus

You don’t need to submit a search string from the frontend either. Say you wanted to add a box that listed posts containing the word “Moomins” ( because everyone loves moomins ).

I could do this by doing a post query with the s parameter, e.g.:

$q = new WP_Query( 's=Moomins' );
$while ( $q->have_posts() ) {
    $q->the_post();
    the_title();
}
wp_reset_postdata(); // clean up after ourselves

And hey presto, a list of titles of posts from a search for “Moomins”