#php #wordpress #woocommerce
#php #wordpress #woocommerce
Вопрос:
Я использую woocommerce для своего веб-сайта, но поскольку у меня есть только один основной продукт и два аксессуара (сопутствующие товары), мне не нужна классическая страница магазина или отдельные страницы для каждого моего продукта. У моего основного продукта есть изменение цвета.
Я хочу иметь кнопку «Добавить в корзину» с раскрывающимся списком «Изменение цвета» и полем «количество» на одной из моих обычных почтовых страниц. Точно так же, как на странице с одним товаром, но встроено в мою собственную страницу, и без частей страницы с одним товаром, которые мне не нужны (описание, …).
Я, наконец, решил добиться этого, используя два пользовательских коротких кода, которые я создал: [my_vc_product_price id="xxx"]
и [my_vc_add2cart_variable_product id="xxx"]
. Так что я могу разместить их там, где захочу.
Но моя проблема в том, что поведение выпадающего меню доступность варианта кнопка добавить в корзину отличается от поведения этих элементов на странице с одним товаром: — доступность варианта не отображается, когда я выбираю цвет в выпадающем меню; — кнопка добавить в корзину не отключается, когда в выпадающем меню не выбран цвет (она должна быть отключена и активна только при выборе цвета).
Отобразить цену было легко, используя некоторый код, найденный в Интернете:
/**
* Add shortcode to allow to display product price in a page
*/
function my_vc_display_product_price( $args ) {
$product_id = $args['id'];
$product = wc_get_product( $product_id );
echo '<p class="price">' . $product->get_price_html() . '</p>';
}
add_shortcode( 'my_vc_product_price', 'my_vc_display_product_price');
Чтобы получить тот же графический результат, мне просто нужно было добавить несколько классов CSS в строку: «woocommerce» и «product».
Код для отображения выпадающего меню количество и кнопка «Добавить в корзину» почти такие же, как в variable.php файл найден в plugins / woocommerce / templates /single-product /добавить в корзину /. Единственное, что действительно меняется, это то, что вам нужно получить «атрибуты вариации» продукта, а не атрибуты.
$attributes = $product->get_variation_attributes();
$attribute_keys = array_keys( $attributes );
Итак, полный код функции:
/**
* Add shortcode to allow to display an add to cart button with dropdown menu for variation attributes
*/
function my_vc_add_to_cart_button_variable_product( $args ) {
global $product;
$product_id = $args['id'];
$product = wc_get_product( $product_id );
if( $product->is_type( 'variable' )) {
$attributes = $product->get_variation_attributes();
$attribute_keys = array_keys( $attributes );
$available_variations = array( $product->get_available_variations() );
do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->get_id() ); ?>" data-product_variations="<?php echo htmlspecialchars( wp_json_encode( $available_variations ) ) ?>">
<?php do_action( 'woocommerce_before_variations_form' ); ?>
<?php if ( empty( $available_variations ) amp;amp; false !== $available_variations ) : ?>
<p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
<?php else : ?>
<table class="variations" cellspacing="0">
<tbody>
<?php foreach ( $attributes as $attribute_name => $options ) : ?>
<tr>
<td class="value">
<?php
$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( stripslashes( urldecode( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ) ) : $product->get_variation_default_attribute( $attribute_name );
wc_dropdown_variation_attribute_options( array( 'options' => $options, 'attribute' => $attribute_name, 'product' => $product, 'selected' => $selected ) );
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<div class="single_variation_wrap">
<?php
/**
* woocommerce_before_single_variation Hook.
*/
do_action( 'woocommerce_before_single_variation' );
/**
* woocommerce_single_variation hook. Used to output the cart button and placeholder for variation data.
* @since 2.4.0
* @hooked woocommerce_single_variation - 10 Empty div for variation data.
* @hooked woocommerce_single_variation_add_to_cart_button - 20 Qty and cart button.
*/
do_action( 'woocommerce_single_variation' );
?>
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
<div class="woocommerce-variation-price">{{{ data.variation.price_html }}}</div>
<div class="woocommerce-variation-availability">{{{ data.variation.availability_html }}}</div>
</script>
<script type="text/template" id="tmpl-unavailable-variation-template">
<p><?php _e( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ); ?></p>
</script>
<?php
/**
* woocommerce_after_single_variation Hook.
*/
do_action( 'woocommerce_after_single_variation' );
?>
</div>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_after_variations_form' ); ?>
</form>
<?php
do_action( 'woocommerce_after_add_to_cart_form' );
}
}
add_shortcode( 'my_vc_add2cart_variable_product', 'my_vc_add_to_cart_button_variable_product');
Есть идеи, что происходит не так? Я не понимаю, если код тот же, почему он не выполнялся так же. Чего-то не хватает, потому что этот код находится за пределами страниц woocommerce?
Ответ №1:
попробуйте использовать следующий код
function add_to_cart_form_shortcode( $atts ) {
if ( empty( $atts ) ) {
return '';
}
if ( ! isset( $atts['id'] ) amp;amp; ! isset( $atts['sku'] ) ) {
return '';
}
$args = array(
'posts_per_page' => 1,
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
);
if ( isset( $atts['sku'] ) ) {
$args['meta_query'][] = array(
'key' => '_sku',
'value' => sanitize_text_field( $atts['sku'] ),
'compare' => '=',
);
$args['post_type'] = array( 'product', 'product_variation' );
}
if ( isset( $atts['id'] ) ) {
$args['p'] = absint( $atts['id'] );
}
$single_product = new WP_Query( $args );
$preselected_id = '0';
if ( isset( $atts['sku'] ) amp;amp; $single_product->have_posts() amp;amp; 'product_variation' === $single_product->post->post_type ) {
$variation = new WC_Product_Variation( $single_product->post->ID );
$attributes = $variation->get_attributes();
$preselected_id = $single_product->post->ID;
$args = array(
'posts_per_page' => 1,
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'p' => $single_product->post->post_parent,
);
$single_product = new WP_Query( $args );
?>
<script type="text/javascript">
jQuery( document ).ready( function( $ ) {
var $variations_form = $( '[data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>"]' ).find( 'form.variations_form' );
<?php foreach ( $attributes as $attr => $value ) { ?>
$variations_form.find( 'select[name="<?php echo esc_attr( $attr ); ?>"]' ).val( '<?php echo esc_js( $value ); ?>' );
<?php } ?>
});
</script>
<?php
}
$single_product->is_single = true;
ob_start();
global $wp_query;
$previous_wp_query = $wp_query;
$wp_query = $single_product;
wp_enqueue_script( 'wc-single-product' );
while ( $single_product->have_posts() ) {
$single_product->the_post()
?>
<div class="single-product" data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>">
<?php woocommerce_template_single_add_to_cart(); ?>
</div>
<?php
}
$wp_query = $previous_wp_query;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
add_shortcode( 'add_to_cart_form', 'add_to_cart_form_shortcode' );
/*Example Usage [add_to_cart_form id=147]*/
Комментарии:
1. Большое вам спасибо! Искал подобное решение целую вечность
2. Можете ли вы опубликовать скриншот того, как это выглядит? Кроме того, нужно ли мне превратить это в плагин или я могу добавить это на страницу как php (в виде «отрывочного» фрагмента php)
3. Вы можете использовать это во фрагменте php как <?php echo do_shortcode(«[add_to_cart_form id=147]»); ?>
4. Это идеально. На самом деле я использую плагин, который изменяет selectfields для переключателей, каким-то образом это тоже изменилось, так что я счастлив: D
5. Здравствуйте, я не понимаю, каков результат этого кода. Я ищу что-то подобное на этой странице darmalux.com/products/smart-watch-5-0?variant=39304396210360 Вы думаете, что можно настроить ваш код так, чтобы в нем было что-то подобное?
Ответ №2:
Это просто идеально! Большое спасибо. Теперь самое сложное: мне нужно понять ваш код и сравнить его с моим 😉
Комментарии:
1. Это просто — получить от вас идентификатор и создать для него html