Создадим функцию, которая будет действовать на конкретный раздел сайта, в частности на конкретную категорию 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 (сначала полное изображение, потом миниатюра)