web-dev-qa-db-ja.com

カスタムCSSクラスをWooCommerceチェックアウトフィールドに追加する

カスタムCSSクラスをWooCommerceチェックアウトフィールドに追加したいのですが。私はTwitterを使用していますBootstrapと私は彼らの.form-controlクラスを使用できるようにしたいと思います。

form-billing.phpのwoocommerceテンプレートフォルダーを調べましたが、各テキストフィールドに.form-controlクラスを追加する場所がわかりません。

form-billing.phpのコードは次のとおりです

<?php
/**
 * Checkout billing information form
 *
 * @author      WooThemes
 * @package     WooCommerce/Templates
 * @version     2.1.2
 */

 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 ?>
 <div class="woocommerce-billing-fields">
<?php if ( WC()->cart->ship_to_billing_address_only() && WC()->cart->needs_shipping() ) : ?>

    <h3><?php _e( 'Billing &amp; Shipping', 'woocommerce' ); ?></h3>

<?php else : ?>

    <h3><?php _e( 'Billing Details', 'woocommerce' ); ?></h3>

<?php endif; ?>

<?php do_action( 'woocommerce_before_checkout_billing_form', $checkout ); ?>

<?php foreach ( $checkout->checkout_fields['billing'] as $key => $field ) : ?>

    <?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>

<?php endforeach; ?>

<?php do_action('woocommerce_after_checkout_billing_form', $checkout ); ?>

<?php if ( ! is_user_logged_in() && $checkout->enable_signup ) : ?>

    <?php if ( $checkout->enable_guest_checkout ) : ?>

        <p class="form-row form-row-wide create-account">
            <input class="input-checkbox" id="createaccount" <?php checked( ( true === $checkout->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true) ?> type="checkbox" name="createaccount" value="1" /> <label for="createaccount" class="checkbox"><?php _e( 'Create an account?', 'woocommerce' ); ?></label>
        </p>

    <?php endif; ?>

    <?php do_action( 'woocommerce_before_checkout_registration_form', $checkout ); ?>

    <?php if ( ! empty( $checkout->checkout_fields['account'] ) ) : ?>

        <div class="create-account">

            <p><?php _e( 'Create an account by entering the information below. If you are a returning customer please login at the top of the page.', 'woocommerce' ); ?></p>

            <?php foreach ( $checkout->checkout_fields['account'] as $key => $field ) : ?>

                <?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>

            <?php endforeach; ?>

            <div class="clear"></div>

        </div>

    <?php endif; ?>

    <?php do_action( 'woocommerce_after_checkout_registration_form', $checkout ); ?>

<?php endif; ?>
</div>

別のテンプレートファイルを調べる必要がありますか?

ありがとう

13
NateW

icc97の答えはほとんどありますが、機能しません。

私はicc97の答えを受け取り、それをデバッグしました:

add_filter('woocommerce_checkout_fields', 'addBootstrapToCheckoutFields' );
public function addBootstrapToCheckoutFields($fields) {
    foreach ($fields as &$fieldset) {
        foreach ($fieldset as &$field) {
            // if you want to add the form-group class around the label and the input
            $field['class'][] = 'form-group'; 

            // add form-control to the actual input
            $field['input_class'][] = 'form-control';
        }
    }
    return $fields;
}
35
Dan Smart

@Peanutsが指摘したように、CSSクラスを特定の入力タイプのみに追加したい場合はどうなりますか?

これまでに投稿された解決策を試してみたところ、(みんなに感謝します!)ロジックが_/woocommerce/includes/wc-template-functions.php_から取られた単純な「スイッチケース」を使用したmodが思い付きました。この関数を使用すると、デフォルトの入力タイプであっても、カスタムの入力タイプであっても、すべての入力タイプを一度にターゲットにすることができます。

入力タイプの_woocommerce_form_field_引数を単に変更するために_$defaults_関数を書き換える必要はありません。この関数を使用すると、フィールドにcssクラスだけでなく、さらに多くのクラスを追加できることにも言及できます。

-だからここに関数があります-

_/*********************************************************************************************/
/** WooCommerce - Modify each individual input type $args defaults /**
/*********************************************************************************************/

add_filter('woocommerce_form_field_args','wc_form_field_args',10,3);

function wc_form_field_args( $args, $key, $value = null ) {

/*********************************************************************************************/
/** This is not meant to be here, but it serves as a reference
/** of what is possible to be changed. /**

$defaults = array(
    'type'              => 'text',
    'label'             => '',
    'description'       => '',
    'placeholder'       => '',
    'maxlength'         => false,
    'required'          => false,
    'id'                => $key,
    'class'             => array(),
    'label_class'       => array(),
    'input_class'       => array(),
    'return'            => false,
    'options'           => array(),
    'custom_attributes' => array(),
    'validate'          => array(),
    'default'           => '',
);
/*********************************************************************************************/

// Start field type switch case

switch ( $args['type'] ) {

    case "select" :  /* Targets all select input type elements, except the country and state select input types */
        $args['class'][] = 'form-group'; // Add a class to the field's html element wrapper - woocommerce input types (fields) are often wrapped within a <p></p> tag  
        $args['input_class'] = array('form-control', 'input-lg'); // Add a class to the form input itself
        //$args['custom_attributes']['data-plugin'] = 'select2';
        $args['label_class'] = array('control-label');
        $args['custom_attributes'] = array( 'data-plugin' => 'select2', 'data-allow-clear' => 'true', 'aria-hidden' => 'true',  ); // Add custom data attributes to the form input itself
    break;

    case 'country' : /* By default WooCommerce will populate a select with the country names - $args defined for this specific input type targets only the country select element */
        $args['class'][] = 'form-group single-country';
        $args['label_class'] = array('control-label');
    break;

    case "state" : /* By default WooCommerce will populate a select with state names - $args defined for this specific input type targets only the country select element */
        $args['class'][] = 'form-group'; // Add class to the field's html element wrapper 
        $args['input_class'] = array('form-control', 'input-lg'); // add class to the form input itself
        //$args['custom_attributes']['data-plugin'] = 'select2';
        $args['label_class'] = array('control-label');
        $args['custom_attributes'] = array( 'data-plugin' => 'select2', 'data-allow-clear' => 'true', 'aria-hidden' => 'true',  );
    break;


    case "password" :
    case "text" :
    case "email" :
    case "tel" :
    case "number" :
        $args['class'][] = 'form-group';
        //$args['input_class'][] = 'form-control input-lg'; // will return an array of classes, the same as bellow
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;

    case 'textarea' :
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;

    case 'checkbox' :  
    break;

    case 'radio' :
    break;

    default :
        $args['class'][] = 'form-group';
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;
    }

    return $args;
}
_

上記の関数は、チェックアウトフォームの入力を一度にターゲットにするという問題を完全に解決しました。これは、チェックアウトフォームのデフォルトの入力タイプまたはカスタムの新しい入力タイプでも非常に簡単です。 @abhisekが彼の答えに示しているように、新しい関数を作成せずに各入力タイプのhtml出力を印刷することはできません。

ボーナス

この関数は、WooCommerceの関数またはチェックアウトページ外のテンプレートによって印刷される他のフォームフィールドにも影響を与える可能性があるようです。 is_page()関数を使用して、チェックアウトページでのみ条件付きで関数を適用できました。チェックアウトページには別のスラッグがある可能性があるため、それを反映するように変更してください。

チェックアウトページにのみ関数を適用する必要がある場合は、次のようにします。

コメントadd_filter()

//add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);

代わりにadd_actionを使用してください

add_action('woocommerce_form_field_args', 'wc_form_field_args', 10, 3);

_function wc_form_field_args( $args, $key, $value = null ) {

...

// Right after 
    return $args;

// Place the following

if ( !is_page('checkout') ) {
  add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
} else {
  remove_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
}


}
_

その後、関数はチェックアウトページフォームにのみ影響します。

20

@Chetanの link and run 回答は、あなたが望むものを提供するものですが、いつものように、それらは決して非常に良い回答ではありません。

これに最適なリソースは、 アクションとフィルターを使用したチェックアウトフィールドのカスタマイズ のWooCommerce Codexページです。

Chetanのページの「WooCommerceチェックアウトフィールドラベルとプレースホルダーテキストのカスタマイズ」には、functions.phpに追加する必要のある次のコードがあります。コードをテストしていません:

// Hook in
add_filter( 'woocommerce_checkout_fields' , 'my_theme_custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function my_theme_custom_override_checkout_fields( $fields ) {
     foreach ($fields as $fieldset) {
         foreach ($fieldset as $field) {
             $field['class'] = array('form-control');
         }
     }
     return $fields;
}
3
icc97

カスタム関数を定義することで問題を解決しました。ロジックはwc-template-functions.phpから直接取得されます(これが正しい方法かどうかはわかりませんが、問題を解決します)。

/*
 * Custom form field function for Bootstrap 3
 */
function bootstrap_woocommerce_form_field( $key, $args, $value = null ) {
    $defaults = array(
        'type'              => 'text',
        'label'             => '',
        'placeholder'       => '',
        'maxlength'         => false,
        'required'          => false,
        'class'             => array(),
        'label_class'       => array(),
        'input_class'       => array(),
        'return'            => false,
        'options'           => array(),
        'custom_attributes' => array(),
        'validate'          => array(),
        'default'           => '',
    );

    $args = wp_parse_args( $args, $defaults  );

    if ( ( ! empty( $args['clear'] ) ) ) $after = '<div class="clear"></div>'; else $after = '';

    if ( $args['required'] ) {
        $args['class'][] = 'validate-required';
        $required = ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce'  ) . '">*</abbr>';
    } else {
        $required = '';
    }

    $args['maxlength'] = ( $args['maxlength'] ) ? 'maxlength="' . absint( $args['maxlength'] ) . '"' : '';

    if ( is_string( $args['label_class'] ) )
        $args['label_class'] = array( $args['label_class'] );

    if ( is_null( $value ) )
        $value = $args['default'];

    // Custom attribute handling
    $custom_attributes = array();

    if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) )
        foreach ( $args['custom_attributes'] as $attribute => $attribute_value )
            $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';

    if ( ! empty( $args['validate'] ) )
        foreach( $args['validate'] as $validate )
            $args['class'][] = 'validate-' . $validate;

    switch ( $args['type'] ) {
    case "country" :

        $countries = $key == 'shipping_country' ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries();

        if ( sizeof( $countries ) == 1 ) {

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']  . '</label>';

            $field .= '<strong>' . current( array_values( $countries ) ) . '</strong>';

            $field .= '<input type="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="' . current( array_keys($countries ) ) . '" ' . implode( ' ', $custom_attributes ) . ' class="country_to_state" />';

            $field .= '</div>' . $after;

        } else {

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">'
                    . '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required  . '</label>'
                    . '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="country_to_state form-control country_select" ' . implode( ' ', $custom_attributes ) . '>'
                    . '<option value="">'.__( 'Select a country&hellip;', 'woocommerce' ) .'</option>';

            foreach ( $countries as $ckey => $cvalue )
                $field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';

            $field .= '</select>';

            $field .= '<noscript><input type="submit" name="woocommerce_checkout_update_totals" value="' . __( 'Update country', 'woocommerce' ) . '" /></noscript>';

            $field .= '</div>' . $after;

        }

        break;
    case "state" :

        /* Get Country */
        $country_key = $key == 'billing_state'? 'billing_country' : 'shipping_country';

        if ( isset( $_POST[ $country_key ] ) ) {
            $current_cc = wc_clean( $_POST[ $country_key ] );
        } elseif ( is_user_logged_in() ) {
            $current_cc = get_user_meta( get_current_user_id() , $country_key, true );
            if ( ! $current_cc) {
                $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_country()) ? WC()->customer->get_country() : WC()->countries->get_base_country());
            }
        } elseif ( $country_key == 'billing_country' ) {
            $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_country()) ? WC()->customer->get_country() : WC()->countries->get_base_country());
        } else {
            $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_shipping_country()) ? WC()->customer->get_shipping_country() : WC()->countries->get_base_country());
        }

        $states = WC()->countries->get_states( $current_cc );

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

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field" style="display: none">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required . '</label>';
            $field .= '<input type="hidden" class="hidden" name="' . esc_attr( $key )  . '" id="' . esc_attr( $key ) . '" value="" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '" />';
            $field .= '</div>' . $after;

        } elseif ( is_array( $states ) ) {

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
            $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="state_select form-control " ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '">
                <option value="">'.__( 'Select a state&hellip;', 'woocommerce' ) .'</option>';

            foreach ( $states as $ckey => $cvalue )
                $field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';

            $field .= '</select>';
            $field .= '</div>' . $after;

        } else {

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
            $field .= '<input type="text" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" value="' . esc_attr( $value ) . '"  placeholder="' . esc_attr( $args['placeholder'] ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
            $field .= '</div>' . $after;

        }

        break;
    case "textarea" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required  . '</label>';

        $field .= '<textarea name="' . esc_attr( $key ) . '" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '"' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>'. esc_textarea( $value  ) .'</textarea>
            </div>' . $after;

        break;
    case "checkbox" :

        $field = '<div class="checkbox form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
                <label for="' . esc_attr( $key ) . '" class="checkbox ' . implode( ' ', $args['label_class'] ) .'" ' . implode( ' ', $custom_attributes ) . '>
                    <input type="' . esc_attr( $args['type'] ) . '" class="input-checkbox" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="1" '.checked( $value, 1, false ) .' />'
                    . $args['label'] . $required . '</label>
            </div>' . $after;

        break;
    case "password" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';

        $field .= '<input type="password" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
            </div>' . $after;

        break;
    case "text" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required . '</label>';

        $field .= '<input type="text" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
            </div>' . $after;

        break;
    case "select" :

        $options = '';

        if ( ! empty( $args['options'] ) )
            foreach ( $args['options'] as $option_key => $option_text )
                $options .= '<option value="' . esc_attr( $option_key ) . '" '. selected( $value, $option_key, false ) . '>' . esc_attr( $option_text ) .'</option>';

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';

            $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="select form-control" ' . implode( ' ', $custom_attributes ) . '>
                    ' . $options . '
                </select>
            </div>' . $after;

        break;
    default :

        $field = apply_filters( 'woocommerce_form_field_' . $args['type'], '', $key, $args, $value );

        break;
    }

    if ( $args['return'] ) return $field; else echo $field;
}

すべてのwoocommerce_form_fieldbootstrap_woocommerce_form_fieldに置き換えることを忘れないでください。

3
abhisek