В карточках товаров Woocommerce есть возможность указать два типа сопутствующих товаров – кросселы и апсейлы. Апсейлы – показываются в карточке товаров, а кросселы в корзине, после добавления товара в корзину.
Есть еще возможность показа блока товаров Вам понравится, но они берутся автоматом из таких же категорий или с такими же метками. А если сопутствующими товарами нужно управлять вручную, то апсейлы и кросселы хороши тем, что их можно добавить к товару импортом, указав в соответствующих столбцах нужные артикулы через запятую. Если стоит задача вывести апсейлы как блок Товары аналоги, а кросселы как блок Рекомендуем с этим товаром, то достаточно провести небольшую доработку шаблона карточки товара.
А именно, необходимо перейти в папку вашей темы: /ваша-тема/woocommerce и скопировать из нее файл single-product.php. Этот файл разместить по аналогичному пути в дочерней теме: /дочерняя-тема/woocommerce
В новом файле после строки
<?php endwhile; // end of the loop. ?>
Размещаем код:
<?php
/*эту часть кода копируем из файла ваша-тема/woocommerce/single-product/up-sells.php, это нужно чтобы стиль блока кросселы был такой же как у апсейлов. У разных шаблонов строки могут отличаться!*/
$products = new WP_Query( $args );
global $ваша-тема_woocommerce_loop;
global $ваша-тема_options;
$related_product_display_columns = isset($ваша-тема _options['related_product_display_columns'])?$ ваша-тема _options['related_product_display_columns']:4;
$ ваша-тема_woocommerce_loop['rating'] = 0;
$ ваша-тема _woocommerce_loop['columns'] = $related_product_display_columns;
$ ваша-тема _woocommerce_loop['layout'] = 'slider';
/*конец*/
$crosssell_ids = get_post_meta( get_the_ID(), '_crosssell_ids' );
if( !empty ($crosssell_ids) ){
$crosssell_ids = $crosssell_ids[0];
if(count($crosssell_ids)>0){
$args = array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => apply_filters( 'woocommerce_cross_sells_total', $posts_per_page ),
'orderby' => $orderby,
'post__in' => $crosssell_ids/*Следующий код раскомментируйте, если необходимо в кросселах выводить только товары в наличии. Не потеряйте запятую, она должна быть после $crosssell_ids */
/*,
'meta_query' => array( array ( 'key' => '_stock_status', 'value' => 'instock', 'compare' => '=' ))*/
);
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_cross_sells_columns', $columns );
if ( $products->have_posts() ) : ?>
<div class="upsells products">/*здесь должен быть указан класс как в файле /woocommerce/single-product/up-sells.php */
<h4 class="widget-title"><span><?php _e( 'You may be interested in…', 'ваша-тема' ) ?></span></h4>/*вместо ваша тема указывается то же что в аналогичном коде в файле /woocommerce/single-product/up-sells.php или 'woocommerce' – это для правильной работы перевода, также может потребоваться изменение 'You may be interested in…' )*.
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
</div>
<?php endif;
}
wp_reset_query();
} ?>
</div>
</div>
<?php if ( is_active_sidebar( $right_sidebar ) && (($sidebar == 'right') || ($sidebar == 'both')) ) : ?>
<div class="sidebar woocommerce-sidebar <?php echo esc_attr($sidebar_col) ?>">
<?php dynamic_sidebar( $right_sidebar );?>
</div>
<?php endif; ?>
<?php if (($content_col_number != 12) || ($layout_style != 'full')): ?>
</div>
<?php endif;?>
Если для блока апсейлов необходимо выводить товары из наличия, то по аналогии создаем путем копирования файл:
Дочерняя-тема/woocommerce/single-product/up-sells.php
Заменяем строку:
'meta_query' => $meta_query
на
'meta_query' => array( array ( 'key' => '_stock_status', 'value' => 'instock', 'compare' => '=' ))