get_searchform() Echo Only Bug

get_searchform() is a weirdly done function. It has an $echo argument that should return the search form instead of echoing it when set to false. It works properly unless you include a searchform.php template file in your theme; if you do it refuses to return the search form and always echos, even when $echo is set to false. There are a few ways around this:

1. Just Don’t add a searchform.php File

This isn’t technically a solution so much as it is avoiding the problem in the first place. Technically speaking, you never have to include a searchform.php template file. If you want a custom search form, you can just paste whatever you would have put in the template file into a filter function. That way you get your custom search form and $var=get_search_form( false ) will still work.

Code

Let’s say this is what you would have put into searchform.php:

<div class="custom-search-wrapper">
    <form role="search" method="get" class="custom-searchform searchform" id="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>" >
    <label class="screen-reader-text assistive-text" for="s">Search for:</label>
    <input type="text" value="<?php echo get_search_query(); ?>" name="s" id="s" />
    <input type="submit" id="searchsubmit" value="Search" />
    </form>
</div><!-- /.custom-search-wrapper -->

You would just convert that to a string, and stick it in a filter function:

function themeslug_searchform_filter( $form ) {
// the same text as above just in string format
$searchform = '<div class="custom-search-wrapper">
    <form role="search" method="get" class="custom-searchform" id="searchform" action="' 
    . esc_url( home_url( '/' ) ) . '">
    <label class="screen-reader-text assistive-text" for="s">Search for:</label>
    <input type="text" value="' . get_search_query() . '" name="s" id="s" />
    <input type="submit" id="searchsubmit" value="Search" />
    </form>
</div><!-- /.custom-search-wrapper -->';
}
// then add the filter
add_filter( 'get_searchform', 'themeslug_searchform_filter' );

This is the most tidy solution, but doesn’t really address the problem. If including a searchform.php file would be helpful to you, there are 2 other methods that actually allow you to return the file contents.

2. Use file_get_contents()

Note: this is an insecure, overly complicated solution. You are much better off using the next solution if you want to return the file. Using eval() is forbidden if you want to get your theme in the official WordPress repository, and should generally be avoided due to security concerns, especially when the string you are using eval() on contains user input. Just don’t do it, okay? Here, take some rubbers.

Getting searchform.php via file_get_contents() works great on pure HTML, but if you have any PHP in your searchform.php (and you almost certainly do), we hit some bumps in the road. This is because file_get_contents() will return the source of the file, not the parsed output. So the variable would include any <?php and &gt?> tags as literal strings and would just print them unparsed if you tried to echo the raw content.

This means we either need to run an eval() on the PHP parts to get it to work, which makes the Theme Review Unit shit bricks. So just use the last method if you really need to include the template file.

3. MOAR OBJECT BUFFERZ!!!

Are you noticing a pattern here? I spiced this one up a bit by registering a global to count the instances of inserted searchforms so each form can have a unique ID if more than one is added to a single page.

function shinra_searchform( $echo=true ) {
    if( $echo ) : get_search_form( true );
    else :  // WP bugfix (compat) (bug) (depreciated)
    
    // manually get count (bypasses action)
    global $shinra;
    if( !isset( $shinra->searchforms ) ) $shinra->searchforms = 0;
    else $shinra->searchforms++;
        
    // load into object buffer
    ob_start();
        get_search_form( true );
    $searchform = ob_get_clean();
        
    // replace dud with actual count & return       
    $searchform = str_replace( 'id="searchform-0"', 'id=searchform-' . $shinra->searchforms . '"', $searchform );
    
    return $searchform;
    endif;
}

Sorry, I did not plan to troll so hard for OB when I sat down to write this…

One Thought on “3 WordPress Hacks to Unlock Some Much-Needed Features

  1. Shariq on April 18, 2013 at 12:38 am said:

    Hi,

    Thanks for the great post. However, I am having trouble implementing it. I am trying to change the look of my searchform. It basically needs to have two text fields. I want this ti be in form of a plugin, which anyone can activate. SO obviously I do not have any control over searchform.php. This made me look at your code snippet.

    I copied your code as it is and added a filter like: add_filter(‘get_search_form’,'shinra_searchform’); However, the code seems to go in an infinite loop. I put an echo statement after lines 11 and 12. The one after 12 never gets printed while the one after line 11 keeps on getting printed continously.

    I tried changing the filter to pass the argument to: 1. add_filter(‘get_search_form’,shinra_searchform(true),1); 2. add_filter(‘get_search_form’,shinra_searchform(false),1); 3. add_filter(‘get_search_form’,shinra_searchform($echo),1); But none of these work.

    Can you please help me out.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation