Создадим функцию, которая будет действовать на конкретный раздел сайта, в частности на конкретную категорию woocommerce. Задачу разобьем на 2 этапа: выборка категорий необходимых для воздействия и непосредственно функция.
Вывод определенного раздела
Фактически на этом этапе нам нужно автоматизировать подбор категорий воздействия. Начиная от родительских категорий — получить дочерние разделы.
Выводим записи всех подкатегорий определенной категории woocommerce, с разделением по каждой подкатегории. 938 — это базовая категория с подкатегориями которой нам нужно работать.
<?php $terms = get_terms( array( 'taxonomy' => 'product_cat', 'hide_empty' => false, 'pad_counts'=> true, 'orderby' => 'name', 'child_of' => 938 ) ); ?> <?php if($terms) : ?> <?php foreach($terms as $term) : ?> <?php echo $term->name;?><br> <?php $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'ACS', 'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'id', 'terms' => $term->term_id, ) )); $postslist = get_posts( $args ); ?> <ul><?php foreach ($postslist as $post) : setup_postdata($post); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title();?></a></li> <?php endforeach; ?> </ul> <?php endforeach; ?> <?php endif; ?>
Выводим записи всех подкатегорий определенной категории woocommerce, без разделения, только записи одна за одной.
<?php $terms = get_terms( array( 'taxonomy' => 'product_cat', 'hide_empty' => false, 'pad_counts'=> true, 'orderby' => 'name', 'child_of' => 938 ) ); ?> <?php if($terms) : ?> <?php foreach($terms as $term) : ?> <?php echo $term->name;?><br> <?php $all_term_ids[] = $term->term_id;?> <?php endforeach; ?> <?php endif; ?> <?php $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'ACS', 'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'id', 'terms' => $all_term_ids ) )); $postslist = get_posts( $args ); ?> <ul><?php foreach ($postslist as $post) : setup_postdata($post); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title();?></a></li> <?php endforeach; ?></ul>
Формировать массив записей можно более коротким способом. Таксономия становиться одним из параметров, причем таким образом можно прописывать несколько таксономий. Но в данном случае необходимо указывать не ID, а slug термина.
$postslist = get_posts( array( 'posts_per_page' => 5, 'orderby' => 'rand', 'post_type' => 'product', 'product_cat' => $term->slug ) );
Можно просто получить список дочерних терминов:
<?php $args = array( 'taxonomy' => 'product_cat', 'hide_empty' => false, 'pad_counts'=> true, 'orderby' => 'name', 'child_of' => 767 ); $terms = get_terms( $args ); ?> <?php foreach($terms as $term) : ?> <?php echo $term->name;?> (<?php echo $term->term_id;?>)<br> <?php endforeach; ?>
В функции get_terms в параметрах child_of и parent — может быть только одно число. А как быть если нам нужно получить дочерние категории двух и более элементов.
Пример: Вывод объявления перед товарами конкретной категории со всеми подкатегориями
// Кратность пачке
function wc_сonditions_multiplicity() {
$args = array(
'child_of' => 6, //категория ламинат
'hide_empty' => 1,
'depth' => -1,
'taxonomy' => 'product_cat',
);
$list_product_categoryes = get_categories( $args );
$category_ids = array();
foreach($list_product_categoryes as $product_category) $category_ids[] = $product_category->term_id;
global $product;
$cur_term = get_the_terms($product->id, 'product_cat');
if (in_array($cur_term[0]->term_id, $category_ids)) {
echo '<p class="multiplicity">Ламинат продается кратно упаковке.</p>';
}
}
add_filter( 'woocommerce_single_product_summary', 'wc_сonditions_multiplicity', 6 );
Несколько child_of категорий
Функция с условием
Применяем функцию к подкатегориям определенной категории. В данном примере к товарам категории (с id 799) к цене добавиться «от …»
function bd_rrp_price_html( $price, $product ) {
global $product;
$cur_term = get_the_terms($product->id, 'product_cat');
if($cur_term[0]->term_id == 799) {
$price = 'от ' . $price;
return $price;
}
return $price;
}
add_filter( 'woocommerce_get_price_html', 'bd_rrp_price_html', 10, 2 );
Условие для нескольких категорий (+ доработан стиль вывода woocommerce):
function bd_rrp_price_html( $price, $product ) {
$os = array('1011','939','940','941','942','943','979','945','946');
global $product;
$cur_term = get_the_terms($product->id, 'product_cat');
if (in_array($cur_term[0]->term_id, $os)) {
$price = '<span class="woocommerce-Price-amount amount"><span class="amount rubl">от </span></span>' . $price;
return $price;
}
return $price;
}
add_filter( 'woocommerce_get_price_html', 'bd_rrp_price_html', 10, 2 );
Еще один способ выборки по нескольким категориям (но более длинный):
// Кратность Сайдинг и фасадная доска
function wc_сonditions_multiplicity_saiding() {
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => array(504, 505, 509, 508, 517, 515, 516, 513, 514, 512, 202, 203, 204)
)
)
);
$list_products = get_posts( $args );
foreach($list_products as $list_product) $list_ids[] = $list_product->ID;
global $product;
if (in_array($product->id, $list_ids)) {
echo '<p class="multiplicity">Товар продается кратно упаковке.</p>';
}
}
add_filter( 'woocommerce_single_product_summary', 'wc_сonditions_multiplicity_saiding', 6 );
Стиль надписи про кратность упаковки:
p.multiplicity {
margin-bottom: 15px;
border: 2px solid #db5757;
color: #db5757;
font-weight: 600;
text-align: center;
padding: 12px;
transform: rotate(-2deg);
}
Action внутри Action
Еще один пример функции зависящей от категории товара:
function chanes_archive_description( $product ) {
global $product;
$cur_term = get_the_terms($product->id, 'product_cat');
if ($cur_term[0]->term_id != 1018) {
remove_action( 'woocommerce_archive_description', 'woocommerce_taxonomy_archive_description', 10 );
add_action( 'woocommerce_after_shop_loop', 'woocommerce_taxonomy_archive_description', 100 );
}
}
add_action( 'body-after', 'chanes_archive_description', 10, 2 );
Мы проверяем если категория товара не 1018, то меняем местами товары и описание категории, если это категория 1018, то описание будет выше товаров. Функцию привязываем к любому доступному action (я создал пользовательский action после открывающего тэга body).
Цикл внутри функции
Создаем цикл записей непосредственно в функции
// Выводим Авторские изделия под Похожими товарами
function add_autor_product() {
$args = array(
'posts_per_page' => 3,
'cat' => 52
);
echo '<h3>Авторские изделия</h3>';
echo '<div id="posts-archive">';
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post);
echo '<div class="hentry" id="post-'.$post->ID.'">';
$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'has_post_thumbnail' );
$url = $thumb['0'];
remove_filter( 'the_content', 'wpautop' );
echo '<a href="'.$url.'">';
$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'rectangle' );
$url = $thumb['0'];
echo '<img src="'.$url.'" title="';
the_content();
echo '">';
echo '</a>';
echo '<h3 class="post-title">';
the_title();
echo '</h3>';
echo '</div>';
endforeach;
echo '</div>';
wp_reset_postdata();
};
add_action( 'tab_woocommerce_related_products', 'add_autor_product', 25 );
В данной функции есть и другие интересные особенности:
- the_content(); и the_title(); нужно выводить без echo
- локальное отключение фильтра wpautop перед выводом the_content(); — remove_filter( ‘the_content’, ‘wpautop’ );
- двойной вывод wp_get_attachment_image_src и перезапись переменной $thumb (сначала полное изображение, потом миниатюра)
