Не могу вывести товары на странице должным образом
У меня выводятся товары на странице - https://snabtorgrt.ru/catalog/stroitelnye-tenty/ (не только на этой странице, просто другие аналогичные)
Я использую плагин Woocommerce для их вывода.
У каждого товара есть атрибут - вес, площадь и тд.
Мне нужно чтоб они выводились по возрастанию значений своих атрибутов, т.е есть веса - 60г, 90г, 100г и тд и надо чтоб вот в таком порядке они выводились(тоже самое и с другими числовыми атрибутами).
Так же надо чтоб выводились по возрастанию цены, одновременно с атрибутами,т.е вначале идут все товары с 60г и у них цена по возрастанию, потом 90г и тд
Не могу такое реализовать, просьба помочь, завис на этом 4 день
То есть чтобы сначала отображались все вес + цена по возрастанию... Я бы конечно ещё сортировку ввел в разных вариантых. В общем чтобы помоч надо покатать тестово. В течении дня буду посвободней, постараюсь решение дать.
Все я покатал, но учитывал я такие вводные от вас:
Атрибут "вес" хранится как термин таксономии (у вас на сайте pa_ves). То есть важно, чтобы атрибут сохранялся не в мету товара, а именно был в атрибутах как архив. В случае если атрибут сохраняется как мета то условности будут другие.
В атрибутах именно цифры, как у вас на сайте
Что вы итоге надо делать? Можно заюзать pre_get_posts чтобы изменить объект, но так как у нас WooСommerce правильно наверное будет использовать woocommerce_product_query
В итоге у меня получилось следующее:
add_action( 'woocommerce_product_query', 'air_sort_products_by_taxonomy_and_price' ); function air_sort_products_by_taxonomy_and_price( $q ) { if ( is_shop() || is_product_category() ) { // исполльзуем только в катах и в шопе $taxonomy = 'pa_ves'; $terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, ) ); /* * Дальше происходит проверка на ошибки и пустоту массива терминов, наверняка такие будут. * Если все в порядке, мы сортируем массив $terms по имени термина (которое, как предполагается, является числом). */ if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) { usort( $terms, function ( $a, $b ) { return intval( $a->name ) - intval( $b->name ); } ); $term_ids = wp_list_pluck( $terms, 'term_id' ); $product_ids = array(); foreach ( $term_ids as $term_id ) { $products = new WP_Query( array( 'post_type' => 'product', 'tax_query' => array( array( 'taxonomy' => $taxonomy, 'field' => 'term_id', 'terms' => $term_id, ), ), // о чем я говорил ранее, атрибуты в таксе должны быть 'meta_key' => '_price', 'orderby' => 'meta_value_num', // cортируем по meta_key 'order' => 'ASC', 'fields' => 'ids', ) ); if ( $products->have_posts() ) { $product_ids = array_merge( $product_ids, $products->posts ); } } $q->set( 'post__in', $product_ids ); $q->set( 'orderby', 'post__in' ); } } }В результате мы получаем необходимую сортировку по атрибутам и по цене:
Ну и если надо отсортировать по второму атрибуту, примерно будет так
add_action( 'woocommerce_product_query', 'air_sort_products_by_taxonomy_several_and_price' ); function air_sort_products_by_taxonomy_several_and_price( $q ) { if ( is_shop() || is_product_category() ) { $taxonomy1 = 'pa_ves'; // Первая такса $taxonomy2 = 'pa_test'; // Вторая таксономия какая там у вас $terms1 = get_terms( array( 'taxonomy' => $taxonomy1, 'hide_empty' => false, ) ); $terms2 = get_terms( array( 'taxonomy' => $taxonomy2, 'hide_empty' => false, ) ); /* * Тут тоже самое только добавлем для проверки второй */ if ( ! is_wp_error( $terms1 ) && ! empty( $terms1 ) && ! is_wp_error( $terms2 ) && ! empty( $terms2 ) ) { usort( $terms1, function ( $a, $b ) { return intval( $a->name ) - intval( $b->name ); } ); usort( $terms2, function ( $a, $b ) { return intval( $a->name ) - intval( $b->name ); } ); $product_ids = array(); foreach ( $terms1 as $term1 ) { foreach ( $terms2 as $term2 ) { $products = new WP_Query( array( 'post_type' => 'product', 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => $taxonomy1, 'field' => 'term_id', 'terms' => $term1->term_id, ), array( 'taxonomy' => $taxonomy2, 'field' => 'term_id', 'terms' => $term2->term_id, ), ), 'meta_key' => '_price', 'orderby' => 'meta_value_num', 'order' => 'ASC', 'fields' => 'ids', ) ); if ( $products->have_posts() ) { $product_ids = array_merge( $product_ids, $products->posts ); } } } $q->set( 'post__in', $product_ids ); $q->set( 'orderby', 'post__in' ); } } }Сразу скажу, что по второму атрибуту я не тестировал, но по-моему направление правильное, там доделаете и все модифицируете.