0

By default the checkout fields are wrapped inside <p class="form-row... HTML by the woocommerce_form_field() core function (see $field_container) - I want to change that bahaviour. How could this be done without altering the core function?

4

The woocommerce_form_field() is a pluggable function, defined as follows:

if ( ! function_exists( 'woocommerce_form_field' ) ) {

    /**
     * Outputs a checkout/address form field.
     *
     * @param string $key Key.
     * @param mixed  $args Arguments.
     * @param string $value (default: null).
     * @return string
     */
    function woocommerce_form_field( $key, $args, $value = null ) {
        ...
    }
}

So you can copy the whole code into your theme's functions.php file, and modify the form field wrapper to suit your requirements, like so where I changed the wrapper's tag from p to div:

if ( ! function_exists( 'woocommerce_form_field' ) ) {

    /**
     * Outputs a checkout/address form field.
     *
     * @param string $key Key.
     * @param mixed  $args Arguments.
     * @param string $value (default: null).
     * @return string
     */
    function woocommerce_form_field( $key, $args, $value = null ) {
        ...
        $field_container = '<div class="form-row %1$s" id="%2$s" data-priority="' . esc_attr( $sort ) . '">%3$s</div>';

        switch ( $args['type'] ) {
            ...
            case 'state':
                ...

                if ( is_array( $states ) && empty( $states ) ) {

                    $field_container = '<div class="form-row %1$s" id="%2$s" style="display: none">%3$s</div>';

                    ...

                } ...
            ...
        }

        ...
    }
}

Or you can use the woocommerce_form_field filter, like so (here I used preg_replace() to change the wrapper's tag from p to div):

add_filter( 'woocommerce_form_field', 'my_woocommerce_form_field' );
function my_woocommerce_form_field( $field ) {
    return preg_replace(
        '#<p class="form-row (.*?)"(.*?)>(.*?)</p>#',
        '<div class="form-row $1 test"$2>$3</div>',
        $field
    );
}

The alternate method worked well in my case, but of course, there were no other (plugin, theme, or custom) code that changes the wrapper's markup/HTML.

Hope that helps.

  • Just one more question: How did you find out that it is a pluggable function? I mean the list in the link provided by you states only WP functions, without any reference to woocommerce. So how could I recognize a pluggable function in future? – chevallier Oct 4 '18 at 19:04
  • That link is for a generic intro to pluggable functions. The key point is, if you see if ( ! function_exists('{FUNCTION NAME}') ), the function is pluggable, which means you can override it by defining it before a theme or plugin defines it. See this, though that's not a reference of WC's pluggable functions. :) – Sally CJ Oct 4 '18 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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