Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую!

Не могу вывести товары на странице должным образом

У меня выводятся товары на странице - https://snabtorgrt.ru/catalog/stroitelnye-tenty/ (не только на этой странице, просто другие аналогичные)

Я использую плагин Woocommerce для их вывода.

У каждого товара есть атрибут - вес, площадь и тд.

Мне нужно чтоб они выводились по возрастанию значений своих атрибутов, т.е есть веса - 60г, 90г, 100г и тд и надо чтоб вот в таком порядке они выводились(тоже самое и с другими числовыми атрибутами).

Так же надо чтоб выводились по возрастанию цены, одновременно с атрибутами,т.е вначале идут все товары с 60г и у них цена по возрастанию, потом 90г и тд

Не могу такое реализовать, просьба помочь, завис на этом 4 день

Заметки к вопросу:
Dan Zakirov 1.5 года назад

То есть чтобы сначала отображались все вес + цена по возрастанию... Я бы конечно ещё сортировку ввел в разных вариантых. В общем чтобы помоч надо покатать тестово. В течении дня буду посвободней, постараюсь решение дать.

0
Sultan
1.5 года назад
  • 2
    Dan Zakirov 754 air-wp.com

    Все я покатал, но учитывал я такие вводные от вас:

    • Атрибут "вес" хранится как термин таксономии (у вас на сайте pa_ves). То есть важно, чтобы атрибут сохранялся не в мету товара, а именно был в атрибутах как архив. В случае если атрибут сохраняется как мета то условности будут другие.

    • В атрибутах именно цифры, как у вас на сайте

    • Я учел только 1 атрибут 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' );
    		}
    	}
    }

    Сразу скажу, что по второму атрибуту я не тестировал, но по-моему направление правильное, там доделаете и все модифицируете.

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация