wordpress 将自定义 css 类添加到 WooCommerce 结帐字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23943791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add custom css class to WooCommerce checkout fields
提问by NateW
I would like to be able to add a custom CSS class to my WooCommerce checkout fields. I'm using twitter Bootstrap and I would like to be able to use their .form-control class.
我希望能够将自定义 CSS 类添加到我的 WooCommerce 结帐字段。我正在使用 twitter Bootstrap,我希望能够使用他们的 .form-control 类。
I looked in the woocommerce templates folder in form-billing.php
but I'm not sure where to add the .form-control
class to each text field.
我查看了 woocommerce 模板文件夹,form-billing.php
但我不确定将.form-control
类添加到每个文本字段的位置。
Here is the code for form-billing.php
这是代码 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 & 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>
Do I need to to look in another template file?
我需要查看另一个模板文件吗?
Thanks
谢谢
回答by Dan Smart
icc97's answer is almost there but doesn't work.
icc97's answer几乎就在那里,但不起作用。
I took icc97's answer, and debugged it:
我拿了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;
}
回答by Adriano Monecchi
As @Peanuts pointed out, what if we want to add CSS classes to certain input types only?
正如@Peanuts 指出的那样,如果我们只想将 CSS 类添加到某些输入类型怎么办?
After experimenting with the solutions posted here so far, (thanks to everybody!), I've came up with a mod using a simple "switch case", in which the logic is taken from /woocommerce/includes/wc-template-functions.php
. The function allow us to target all the input types at once, be it the default input types or even custom ones.
在尝试了到目前为止发布的解决方案之后,(感谢大家!),我想出了一个使用简单的“开关盒”的 mod,其中的逻辑取自/woocommerce/includes/wc-template-functions.php
. 该函数允许我们一次定位所有输入类型,无论是默认输入类型还是自定义输入类型。
There's no need to rewrite the woocommerce_form_field
function to simply change the $defaults
args for the input types. It is valid to mention that the function also allow us to add much more than just css classes to the fields.
无需重写woocommerce_form_field
函数来简单地更改$defaults
输入类型的参数。值得一提的是,该函数还允许我们向字段中添加的不仅仅是 css 类。
-- So here's the function --
-- 所以这是函数 --
/*********************************************************************************************/
/** 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;
}
The function above completely solved the issue of targeting the checkout form inputs all at once, which is really straight forward for the checkout form default input types or even custom new ones. It seems not to be possible though, to print each input type html output without creating a new function as @abhisek shows on his answer.
上述功能完全解决了一次性针对结账表单输入的问题,这对于结账表单默认输入类型甚至自定义新输入类型来说非常简单。但是,似乎不可能在不创建新函数的情况下打印每个输入类型的 html 输出,如@abhisek 在他的回答中所示。
Bonus
奖金
It seems that the function might also affect other forms fields printed by WooCommerce's functions or templates outside the checkout page.
I've managed to conditionally apply the function only when on the checkout page by using the is_page()
function. Your checkout page might have a different slug, so change that to reflect it accordingly.
该功能似乎还可能影响结帐页面之外由 WooCommerce 的功能或模板打印的其他表单字段。我已经设法通过使用该is_page()
功能在结帐页面上有条件地应用该功能。您的结帐页面可能有不同的 slug,因此请相应地更改它以反映它。
If you need to apply the function only for the checkout page, do as follows:
如果您只需要在结账页面应用该功能,请执行以下操作:
Comment add_filter()
评论 add_filter()
//add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
//add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
And use add_action instead
并使用 add_action 代替
add_action('woocommerce_form_field_args', 'wc_form_field_args', 10, 3);
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);
}
}
After that, the function will only affect the checkout page form.
之后,该功能只会影响结帐页面表单。
回答by icc97
@Chetan's link and runanswer does kind of give you what you want, but as ever they're never very good answers.
@Chetan 的链接和运行答案确实给了你你想要的东西,但它们从来都不是很好的答案。
The best resource for this is the WooCommerce Codex page on Customizing checkout fields using actions and filters.
最好的资源是 WooCommerce Codex 页面上使用操作和过滤器自定义结帐字段。
In the 'Customizing WooCommerce Checkout Field Labels and Placeholder Text' in Chetan's page you have the following code which you need to add to your functions.php, I've modified it in such a way that it should do what you want, but I haven't tested the code:
在 Chetan 页面的“自定义 WooCommerce Checkout 字段标签和占位符文本”中,您需要将以下代码添加到您的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;
}
回答by abhisek
I am fixed the issue by defining a custom function. The logic is taken directly from wc-template-functions.php (I am not sure if this is the right way but it does solve the problem).
我通过定义自定义函数解决了这个问题。逻辑直接取自 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…', '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…', '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;
}
Don't forget to replace all occurrences of woocommerce_form_field
with bootstrap_woocommerce_form_field
Hope it helps!
不要忘记,以取代所有出现woocommerce_form_field
与bootstrap_woocommerce_form_field
希望它能帮助!