Customizing Wordpress search form template (Genesis)
Asked Answered
P

1

6

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

Parry answered 8/3, 2017 at 13:18 Comment(7)
Where is you my_search_form() function?Calendra
In the searchform.php I remove the original genesis_search_form() filter and replace all instances of genesis_search_form() with my_search_form() and add the autocomplete="off" to the code. The errors are error 500 where the entire or parts of the page appear white, it seems that the code can't run properly outside of its original location, but I wanted an alternative to avoid editing the parent theme framework directly.Parry
What is the reson for removing the original... There should be no reason that it would affect your new form as long as you call your form instead of genesis.Angilaangina
Thought that there would be conflict. But having it there didn't help either way.Parry
It currently works perfectly on the homepage, but in any other page only the header and the tagline are generated.Parry
wouldn't a 2-3 lines javascript solution be the best choice here if this trouble is done only for the autocomplete feature?Eustis
Probably, I thought about that at first. If it was a permanent element I would have done it with jQuery, but then thought I that generating it with php and then add the extra elements with jQuery wouldn't be very efficient. So in the end, I opted for using only 1 language for its entire generation.Parry
A
1

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.

Antler answered 10/3, 2017 at 21:49 Comment(6)
Thank you for your response. Your approach is interesting. But I think that something is not right because when I wright that code in the functions.php only the the head and an empty body without classes are generated in all the pages.Parry
@Parry please see my updated answer and try the new code. Don't forget to disable all the filters and changes you have made to the search functions of the genesis theme.Antler
Thank you for trying. I'm so sorry but I just can't reproduce your example, even after downloading fresh framework and genesis sample. Now it removes all the search forms, I will try to upload images to show you soon.Parry
@Parry which version of genesis and PHP do you have? Can you please try to debug this by adding return 'debug: <pre>'.htmlentities($form_html).'</pre>'; to the end of my_search_form_filter function and update with what you see instead of the search boxes?Antler
PHP version: 5.6.29. The result was: "debug: "Parry
Let us continue this discussion in chat.Antler

© 2022 - 2025 — McMap. All rights reserved.