I'm trying to put search results into a div with ajax. The issue is I'm getting errors saying undefined function have_posts() when the the search template is accessed. It also took issue with get_header() which was in the search-results.php but I took it out. Here's how I have it setup.

  <div id="my_search">
   <form role="search" method="get" id="searchform" action="http://myurl.com/" >
    <input type="text" value="" name="s" id="s" />
    <input type="submit" id="searchsubmit" value="Search" />
  <div id="results"></div>
  <script type="text/javascript">
     var search_val=$("#s").val(); 

And here is the search-results.php template. I'm wondering if maybe I'm not passing the search results to the template.

 <?php if (have_posts()) : while (have_posts()) : the_post();  ?>
  <li><a title="Permalink to this post" href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a></li>

 <?php endwhile; endif; ?>
 <?php if (!have_posts()) { echo('<li>No results to show.</li>'); } ?>

1 Answer 1


When you load a template file directly that way, you're not loading the WordPress environment, so no WordPress functions are available.

Your two options are to either load the search page on the front end and filter the result, like:

$('#results').load('http://mysite.com/?s=searchterm ul#target');

Or build a search function using WordPress provided AJAX functionality, see AJAX in Plugins.


Here's an example of how I load additional posts via AJAX which you could adapt to create a search function if you wish.

First, in functions.php, I enqueue my javascript and localize the script to pass the AJAX URL that will process my requests. WordPress AJAX uses admin-ajax.php to process all AJAX requests, front or back end:

add_action( 'wp_enqueue_scripts', 'wpa56343_scripts', 100 );

function wpa56343_scripts() {
        get_template_directory_uri() . '/js/scripts.js?ver=1.0',
        array( 'jquery' ),
            'ajaxurl' => admin_url( 'admin-ajax.php' )

In scripts.js, my javascript that calls my AJAX action, and passes a postoffset var so I can pass that to the query. Note also the use of WPaAjax.ajaxurl to pass the URL that will process this request:


    $('#blog-more').click(function(e){ // <- added
        e.preventDefault(); // <- added to prevent normal form submission
        var postoffset = $('.post').length;
                action : 'wpa56343_more',
                postoffset : postoffset
            function( response ) {
                $('#container').append( response );


In functions.php, the function that processes my AJAX request mapped to the action I passed in the javascript above. A stripped down version of WordPress is bootstrapped, so I can access most WordPress functions:

add_action('wp_ajax_wpa56343_more', 'wpa56343_more');
add_action('wp_ajax_nopriv_wpa56343_more', 'wpa56343_more');

function wpa56343_more(){
    global $wp_query;

    $offset = $_POST['postoffset'];
    $args = array(
        'offset' => $offset,
        'posts_per_page' => 10
    $wp_query = new WP_Query( $args );

    get_template_part( 'post-template' );

  • I was trying to adapt this and for some reason when I click search it takes me to another site(myurl.com?s=term). Here is the pastebin of my adaption. What am I doing wrong here? pastebin.com/5CqMhhDD Commented Jun 24, 2012 at 8:58
  • 1
    oh yeah, you had it right in your original code, you need to prevent the default form submission when the search is initiated, see edit above.
    – Milo
    Commented Jun 24, 2012 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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