Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customizing Wordpress search form template (Genesis)

I wanted to change my search form a bit by adding autocomplete="off" to the search input.

I initially looked for a simple filter like the following:

//* Customize search form input box text
add_filter( 'genesis_search_text', 'sp_search_text' );
function sp_search_text( $text ) {
    return esc_attr( 'Search my blog...' );
}

But because the /genesis/lib/structure/search.php did not have any variable like autocomplete="%s", that attribute could not be targeted. I probably had to introduce it directly, so I copied the search.php from the parent theme folder to the child theme folder folder.

The original code of the file was the following:

<?php

/**
 * Replace the default search form with a Genesis-specific form.
 *
 * The exact output depends on whether the child theme supports HTML5 or not.
 *
 * Applies the `genesis_search_text`, `genesis_search_button_text`, `genesis_search_form_label` and
 * `genesis_search_form` filters.
 *
 * @since 0.2.0
 *
 * @return string HTML markup for search form.
 */

add_filter( 'get_search_form', 'genesis_search_form' );

function genesis_search_form() {
    $search_text = get_search_query() ? apply_filters( 'the_search_query', get_search_query() ) : apply_filters( 'genesis_search_text', __( 'Search this website', 'genesis' ) . ' &#x02026;' );

    $button_text = apply_filters( 'genesis_search_button_text', esc_attr__( 'Search', 'genesis' ) );

    $onfocus = "if ('" . esc_js( $search_text ) . "' === this.value) {this.value = '';}";
    $onblur  = "if ('' === this.value) {this.value = '" . esc_js( $search_text ) . "';}";

    // Empty label, by default. Filterable.
    $label = apply_filters( 'genesis_search_form_label', '' );

    $value_or_placeholder = ( get_search_query() == '' ) ? 'placeholder' : 'value';

    if ( genesis_html5() ) {

        $form  = sprintf( '<form %s>', genesis_attr( 'search-form' ) );

        if ( genesis_a11y( 'search-form' ) ) {

            if ( '' == $label )  {
                $label = apply_filters( 'genesis_search_text', __( 'Search this website', 'genesis' ) );
            }

            $form_id = uniqid( 'searchform-' );

            $form .= sprintf(
                '<meta itemprop="target" content="%s"/><label class="search-form-label screen-reader-text" for="%s">%s</label><input itemprop="query-input" type="search" name="s" id="%s" %s="%s" /><input type="submit" value="%s" /></form>',
                home_url( '/?s={s}' ),
                esc_attr( $form_id ),
                esc_html( $label ),
                esc_attr( $form_id ),
                $value_or_placeholder,
                esc_attr( $search_text ),
                esc_attr( $button_text )
            );

        } else {

            $form .= sprintf(
                '%s<meta itemprop="target" content="%s"/><input itemprop="query-input" type="search" name="s" %s="%s" /><input type="submit" value="%s"  /></form>',
                esc_html( $label ),
                home_url( '/?s={s}' ),
                $value_or_placeholder,
                esc_attr( $search_text ),
                esc_attr( $button_text )
            );
        }


    } else {

        $form = sprintf(
            '<form method="get" class="searchform search-form" action="%s" role="search" >%s<input type="text" value="%s" name="s" class="s search-input" onfocus="%s" onblur="%s" /><input type="submit" class="searchsubmit search-submit" value="%s" /></form>',
            home_url( '/' ),
            esc_html( $label ),
            esc_attr( $search_text ),
            esc_attr( $onfocus ),
            esc_attr( $onblur ),
            esc_attr( $button_text )
        );

    }

    return apply_filters( 'genesis_search_form', $form, $search_text, $button_text, $label );

}

Then I removed the original filter and added my filter:

remove_filter( 'get_search_form', 'genesis_search_form' );

add_filter( 'get_search_form', 'my_search_form' );

And added autocomplete="off" to the search input, so the current is:

<?php

/**
 * Replace the default search form with a Genesis-specific form.
 *
 * The exact output depends on whether the child theme supports HTML5 or not.
 *
 * Applies the `genesis_search_text`, `genesis_search_button_text`, `genesis_search_form_label` and
 * `genesis_search_form` filters.
 *
 * @since 0.2.0
 *
 * @return string HTML markup for search form.
 */

remove_filter( 'get_search_form', 'genesis_search_form' );

add_filter( 'get_search_form', 'my_search_form' );

function my_search_form() {
    $search_text = get_search_query() ? apply_filters( 'the_search_query', get_search_query() ) : apply_filters( 'genesis_search_text', __( 'Search this website', 'genesis' ) . ' &#x02026;' );

    $button_text = apply_filters( 'genesis_search_button_text', esc_attr__( 'Search', 'genesis' ) );

    $onfocus = "if ('" . esc_js( $search_text ) . "' === this.value) {this.value = '';}";
    $onblur  = "if ('' === this.value) {this.value = '" . esc_js( $search_text ) . "';}";

    // Empty label, by default. Filterable.
    $label = apply_filters( 'genesis_search_form_label', '' );

    $value_or_placeholder = ( get_search_query() == '' ) ? 'placeholder' : 'value';

    if ( genesis_html5() ) {

        $form  = sprintf( '<form %s>', genesis_attr( 'search-form' ) );

        if ( genesis_a11y( 'search-form' ) ) {

            if ( '' == $label )  {
                $label = apply_filters( 'genesis_search_text', __( 'Search this website', 'genesis' ) );
            }

            $form_id = uniqid( 'searchform-' );

            $form .= sprintf(
                '<meta itemprop="target" content="%s"/><label class="search-form-label screen-reader-text" for="%s">%s</label><input itemprop="query-input" type="search" name="s" id="%s" %s="%s" autocomplete="off" spellcheck="false" autocorrect="off" autocapitalize="off" dir="auto" /><input type="submit" value="%s" /></form>',
                home_url( '/?s={s}' ),
                esc_attr( $form_id ),
                esc_html( $label ),
                esc_attr( $form_id ),
                $value_or_placeholder,
                esc_attr( $search_text ),
                esc_attr( $button_text )
            );

        } else {

            $form .= sprintf(
                '%s<meta itemprop="target" content="%s"/><input itemprop="query-input" type="search" name="s" %s="%s" autocomplete="off" spellcheck="false" autocorrect="off" autocapitalize="off" dir="auto" /><input type="submit" value="%s"  /></form>',
                esc_html( $label ),
                home_url( '/?s={s}' ),
                $value_or_placeholder,
                esc_attr( $search_text ),
                esc_attr( $button_text )
            );
        }


    } else {

        $form = sprintf(
            '<form method="get" class="searchform search-form" action="%s" role="search" >%s<input type="text" value="%s" name="s" class="s search-input" onfocus="%s" onblur="%s" autocomplete="off" spellcheck="false" autocorrect="off" autocapitalize="off" dir="auto" /><input type="submit" class="searchsubmit search-submit" value="%s" /></form>',
            home_url( '/' ),
            esc_html( $label ),
            esc_attr( $search_text ),
            esc_attr( $onfocus ),
            esc_attr( $onblur ),
            esc_attr( $button_text )
        );

    }

    return apply_filters( 'my_search_form', $form, $search_text, $button_text, $label );

}

It currently works perfectly on the homepage, but in any other page only the header and the tagline are generated. I could edit the parent theme files directly but wanted an alternative to avoid messing everything up. Any insight or suggestions?


Documentation for get_search_form

Documentation for genesis_search_form

Documentation for Genesis Snippets

like image 532
SilverLink Avatar asked Nov 08 '22 01:11

SilverLink


1 Answers

I see that the genesis_search_form function applies genesis_search_form filter at the end. Instead of re-writing the whole genesis_search_form function, you can use that to manipulate the form and use DOMDocument inside a new filter to add the autocomplete attribute you want. Try the following code inside your child theme functions.php and see if it works:

add_filter( 'genesis_search_form', 'my_search_form_filter', 5 );
function my_search_form_filter($form) {

    $document = new DOMDocument();
    $document->loadHTML($form);
    $xpath = new DOMXPath($document);
    $input = $xpath->query('//input[@name="s"]');
    if ($input->length > 0) {
        $input->item(0)->setAttribute('autocomplete', 'off');
    }

    # remove <!DOCTYPE 
    $document->removeChild($document->doctype); 
    # remove <html><body></body></html> 
    $document->replaceChild($document->firstChild->firstChild->firstChild, $document->firstChild);
    $form_html = $document->saveHTML();

    return $form_html;
}

Don't forget to disable your code that disables the default get_search_form filter and adds yours.

EDIT

The previous code was wrong, please update with the latest above code that works. I have tested it with genesis and genesis-child themes.

Here you can find my Dev Wordpress site with the genesis theme installed and you can inspect the search input box and see it has the autocomplete attribute set to off: http://wp.dev.lytrax.net/

And here is a screenshot showing the form search input element having the autocomplete attribute:

Wordpress screenshot

EDIT 2

The genesis-sample theme, uses the HTML5 search form and it includes some meta tags inside the code that createDocumentFragment element can handle using appendXML, thus it throws many warnings and it fails to continue. You can't see those PHP warnings, because most likely you have them disabled. Please try my updated code. Add it to the end of the genesis-sample/functions.php file and check if it adds the autocomplete attribute.

like image 172
Christos Lytras Avatar answered Nov 15 '22 04:11

Christos Lytras