Настройте таргетинг на определенную категорию продуктов и ее дочерние элементы в WooCommerce

Я пытаюсь добавить пользовательский контент перед содержимым магазина, но только при просмотре продуктов в определенной категории с дочерними элементами этой категории.

Категории: основная категория - 'события', дочерние категории - 'семинар', 'курс' и 'обучение'< /эм>.

add_action( 'woocommerce_before_shop_loop', 'eventsTerms', 18);
function eventsTerms() {

  $term = get_term_by('name', 'events', 'product_cat');
  $term_id = $term->term_id;
  $taxonomyName = 'product_cat';
  $termChildren = get_term_children( $term_id, $taxonomyName );

foreach ( $termChildren as $child ) {
  $_term = get_term_by( 'id', $child, $taxonomyName );
  $childTerms= ', "' . '' . $_term->name . '"';

  echo $childTerms; // only to see is ok

}

    if ( is_product_category( array("events", $childTerms) ) ) {
    global $product;
    wp_list_categories( 
      array(
          'show_option_all' => 'show all',
          'taxonomy' => 'product_cat',
          'style' => 'none',
          'separator' => '',
          'hide_empty' => 0,
      ));

  }

}

$childTerms возвращает имена всех дочерних категорий, поэтому я хочу использовать условный тег is_product_category с массивом, но мой код по-прежнему работает только с основной категорией «события».

Где ошибка?

ИЗМЕНИТЬ 1

Хорошо, я думал, что причина, по которой он не работает, заключается в том, что implode нельзя использовать в is_product_category() аргументах. Итак, я пытался с json_encode вот так:

add_action( 'woocommerce_before_shop_loop', 'eventsTerms', 18);
function eventsTerms() {

  $term = get_term_by('name', 'events', 'product_cat');
  $term_id = $term->term_id;
  $taxonomyName = 'product_cat';
  $termChildren = get_term_children( $term_id, $taxonomyName );

foreach ( $termChildren as $child ) {
  $_term = get_term_by( 'id', $child, $taxonomyName );
  $childTerms[] = " '".$_term->name."'";
}

$x = implode(",", $childTerms);

$y = json_encode($x);

echo $y; // output as " 'seminarium', 'course', 'training'"

$y2 = preg_replace('/"([a-zA-Z]+[a-zA-Z0-9_]*)":/','$1:', $x); // removing qutes by preg_replace

echo $y2; // output as 'seminarium', 'course', 'training'

    if ( is_product_category( array('events', $y) ) ) {
    global $product;
    wp_list_categories( 
      array(
          'show_option_all' => 0,
          'taxonomy' => 'product_cat',
          'style' => 'none',
          'separator' => '',
          'hide_empty' => 0,
          'child_of' => $term_id,
      ));

  }

}

person Damian    schedule 09.08.2019    source источник


Ответы (1)


Функция get_term_by() работает не с "id", но с "term_id" (или "slug" или "name").
Функция get_term_children() возвращает массив идентификаторов условий. сильный>.
Условная функция is_product_category() принимает массив имен терминов, слагов или идентификаторов, поскольку он основан на функции is_tax().

Вы делаете вещи более сложными, чем они должны быть, и вам не нужен цикл foreach.

Чтобы настроить таргетинг на определенную категорию продуктов и связанные с ней дочерние элементы:

1) На страницах архива:

$term_slug = 'events';
$taxonomy  = 'product_cat';

$term_id   = get_term_by( 'slug', $term_slug, $taxonomy )->term_id; // Get the term ID
$child_ids = get_term_children( $term_id, $taxonomy ); // Get the children terms IDs
$terms_ids = array_merge( $child_ids, array($term_id) ); // an array of all term IDs (main term Id and it's children)

if ( is_product_category( $terms_ids ) ) {
    // Do something
}

Итак, в вашем коде:

add_action( 'woocommerce_before_shop_loop', 'eventsTerms', 18 );
function eventsTerms() {
    $term_slug = 'events';
    $taxonomy  = 'product_cat';

    $term_id   = get_term_by( 'slug', $term_slug, $taxonomy )->term_id; // Get the term ID
    $child_ids = get_term_children( $term_id, $taxonomy ); // Get the children terms IDs
    $terms_ids = array_merge( $child_ids, array($term_id) ); // an array of all term IDs (main term Id and it's children)

    if ( is_product_category( $terms_ids ) ) {
        global $product;
        
        wp_list_categories( array(
            'show_option_all' => 'show all',
            'taxonomy'        => 'product_cat',
            'style'           => 'none',
            'separator'       => '',
            'hide_empty'      => 0,
            'child_of'        => $term_id,
        ) );
    }
}

Код находится в файле functions.php вашей активной дочерней темы (активной активной темы). Проверено и работает.


2) На страницах товаров, товарах в корзине или заказах (вместо архивных страниц):

Вы будете использовать условную функцию has_term(), которая также принимает массив имен терминов, слагов или идентификаторы (третий аргумент (необязательный) — это идентификатор публикации или идентификатор продукта для продуктов WooCommerce):

$term_slug = 'events';
$taxonomy  = 'product_cat';

$term_id   = get_term_by( 'slug', $term_slug, $taxonomy )->term_id; // Get the term ID
$child_ids = get_term_children( $term_id, $taxonomy ); // Get the children terms IDs
$terms_ids = array_merge( $child_ids, [$term_id] ); // an array of all term IDs (main term Id and it's children)

if ( has_term( $terms_ids, $taxonomy, $product_id ) ) {
    // Do something
}
person LoicTheAztec    schedule 10.08.2019
comment
Спасибо за ответ! Я вижу, что в вашем коде есть `is_product_category( $terms_ids )', но мне кажется, что условный тег может содержать только слаги, а не идентификаторы. К сожалению, этот код не работает :( - person Damian; 10.08.2019
comment
И для дочерних терминов тоже работает? В моем случае работает только для родительской категории :/ - person Damian; 10.08.2019
comment
Хорошо, я согласен, в $terms_ids есть массив дочерних терминов. Но это не меняет того факта, что этот скрипт работает только с родительской категорией, я имею в виду товар-категорию/события/, но, например, для. в категории продуктов/событиях/курсах нет. - person Damian; 10.08.2019
comment
Благодаря ответу в другой группе я получаю окончательный рабочий код. Вместо $terms_ids = [$term_id] + $child_ids; Я использую $terms_ids = array_merge($child_ids, [$term_id]); и теперь работает так, как я хочу! - person Damian; 10.08.2019
comment
в случае нескольких основных категорий, как это сделать? - person M. Lak; 12.10.2020