/ Плагины / Варианты сортировки woocommerce

Варианты сортировки woocommerce

HIT

11.03.2017

16831

16

Добавляем свои варианты сортировки в woocommerce, кроме стандартных: по цене, по новизне, по популярности, по рейтингам.

Как организовать сортировку по атрибуту товара

Сортировке поддаются только числовые свойства товаров содержащихся у каждого товара. Сортировка по атрибуту относится к фильтрации. По этой причине пропала возможность с версии WC 3.0 сортировать по рекомендуемым (featured) товарам, т.к. эта особенность стала содержаться не в meta а в дополнительной таксономии product_visibility.

В Woocommerce заложена возможность произвольной сортировки товаров и категорий.

Вариант сортировки: Случайно

// Добавить вариант сортировки: Случайно

add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );
 
function custom_woocommerce_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
	if ( 'random_list' == $orderby_value ) {
		$args['orderby'] = 'rand';
		$args['order'] = '';
		$args['meta_key'] = '';
	}
	return $args;
}
 
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby', 100 );
 
function custom_woocommerce_catalog_orderby( $sortby ) {
	$sortby['random_list'] = __('Случайно');
	return $sortby;
}

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

Вариант сортировки: По названию

// Добавить вариант сортировки: По названию

add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_name_args' );

function custom_woocommerce_get_catalog_ordering_name_args( $args ) {
	$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
	if ( 'name_list' == $orderby_value ) {
		$args['orderby'] = 'name';
		$args['order'] = 'ASC';
		$args['meta_key'] = '';
	}
	return $args;
}

add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_name_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_name_orderby', 1 );

function custom_woocommerce_catalog_name_orderby( $sortby ) {
	$sortby['name_list'] = 'По названию';
	return $sortby;
}

Вариант сортировки: По меткам

// Добавить вариант сортировки: По меткам

add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_tag_args' );
function custom_woocommerce_get_catalog_ordering_tag_args( $args ) {
  $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
    if ( 'tag_list' == $orderby_value ) {
        $args['orderby'] = 'product_tag';//поле по которому сортируем
        $args['order'] = 'ASC';//по возрастанию (ASC) или убыванию (DESC)
        $args['meta_key'] = '';//по конкретному совпадению ключа
    }
    return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_tag_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_tag_orderby', 5 );

function custom_woocommerce_catalog_tag_orderby( $sortby ) {
    $sortby['tag_list'] = 'По меткам';
    return $sortby;
}
Попытался недавно использовать — обнаружил что работает некорректно.

Сначала товары со скидкой

// Сортировка Сначала товары по акции
add_filter( 'woocommerce_get_catalog_ordering_args', 'wcs_get_catalog_ordering_args' );
function wcs_get_catalog_ordering_args( $args ) {
    $orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
     
    if ( 'on_sale' == $orderby_value ) {
        $args['orderby'] = 'meta_value_num';
        $args['order'] = 'DESC';
        $args['meta_key'] = '_sale_price'; 
    }
    return $args;
}
 
add_filter( 'woocommerce_default_catalog_orderby_options', 'wcs_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'wcs_catalog_orderby' );
function wcs_catalog_orderby( $sortby ) {
    $sortby['on_sale'] = 'Сначала товары по акции';
    return $sortby;
}

Работает странно: на одном сайте (с бОльшим количеством товаров) выводил акционные товары на первое место, а на другом сайте оставлял только акционные товары и другие не выводил.

Вариант сортировки: По наличию

// Сортировка по наличию

add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );

function custom_woocommerce_get_catalog_ordering_args( $args ) {
	$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );

	if ( 'stock_list_asc' == $orderby_value ) {
		$args['orderby'] = 'meta_value_num wp_posts.ID';
		$args['order'] = 'ASC';
		$args['meta_key'] = '_stock';
	}
	elseif ( 'stock_list_desc' == $orderby_value ) {
		$args['orderby'] = 'meta_value_num wp_posts.ID';
		$args['order'] = 'DESC';
		$args['meta_key'] = '_stock';
	}

	return $args;
}

add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby' );

function custom_woocommerce_catalog_orderby( $sortby ) {
	$sortby['stock_list_desc'] = 'Остаток: по убыванию';
	$sortby['stock_list_asc'] = 'Остаток: по возрастанию';
	return $sortby;
}

Товары не в наличии в конце

class iWC_Orderby_Stock_Status {
 
	public function __construct() {
		// Check if WooCommerce is active
		if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
			add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
		}
	}
 
	public function order_by_stock_status($posts_clauses) {
		global $wpdb;
		// only change query on WooCommerce loops
		if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
			$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
			$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
			$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
		}
		return $posts_clauses;
	}
}
 
new iWC_Orderby_Stock_Status;

Удаляем варианты сортировки

Чтобы отключить стандартный вариант сортировки, нужно использовать следующую функцию:

function my_woocommerce_catalog_orderby( $orderby ) {
    unset($orderby["price"]);
    unset($orderby["price-desc"]);
    return $orderby;
}
add_filter( "woocommerce_catalog_orderby", "my_woocommerce_catalog_orderby", 20 );

Варианты сортировки woocommerce:

  • По-умолчанию (по сути по дате, либо если настроено по menu_order)
  • По популярности (popularity, на основе количества продаж товаров)
  • По рейтингу (rating)
  • По дате (date, игнорирует menu_order)
  • По возрастанию цены (price)
  • По убыванию цены (price-desc)

Переименовываем варианты сортировки

Это можно сделать с помощью переводов либо функцией:

// Переименовать методы сортировки
add_filter( 'woocommerce_catalog_orderby', 'misha_rename_default_sorting_options' );
function misha_rename_default_sorting_options( $options ){
	$options[ 'date' ] = 'Сначала новинки';
	return $options;
}

Сортировка radio кнопками

Изменяем локальный файл шаблона woocommerce/orderby/orderby.php c

<select name="orderby" class="orderby" aria-label="<?php esc_attr_e( 'Shop order', 'woocommerce' ); ?>">
	<?php foreach ( $catalog_orderby_options as $id => $name ) : ?>
		<option value="<?php echo esc_attr( $id ); ?>" <?php selected( $orderby, $id ); ?>><?php echo esc_html( $name ); ?></option>
	<?php endforeach; ?>
</select>

на

<div aria-label="<?php esc_attr_e( 'Shop order', 'woocommerce' ); ?>">
	<?php foreach ( $catalog_orderby_options as $id => $name ) : ?>
		<label><input type="radio" name="orderby" class="orderby" value="<?php echo esc_attr( $id ); ?>" <?php checked( $orderby, $id ); ?>><?php echo esc_html( $name ); ?></label>
	<?php endforeach; ?>
</div>

И прописываем небольшой скрипт:

jQuery(function(i) {
    i(".woocommerce-ordering").on("change", "input.orderby", function() {
        i(this).closest("form").submit();
    })
});

Сортировка по двум условиям

Данное решение сам еще не тестировал

add_action( 'pre_get_posts', 'mik_exclude_category' );
function mik_exclude_category( $query ) {
    if ( $query->is_main_query() ) {
 
    	$query->set( 'meta_key', '_stock_status' );
        $query->set( 'orderby', array('meta_value' => 'ASC', 'date' => 'DESC') );
 
    }
}

или еще вариант

add_filter( 'woocommerce_shortcode_products_query', function( $args, $atts, $loop_name ){
	if( $loop_name == 'product_category'){
		$args['meta_key'] = '_stock_status';
		$args['orderby'] = array('meta_value' => 'ASC', 'menu_order' => 'ASC');
	}
	return $args;
}, 10, 3);

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Woo Discount Rules PRO

Woo Discount Rules PRO

Обозреваем плагин Woo Discount Rules PRO, конфигурации акций и различные настройки плагина. Каждый второй товар бесплатно Сделаем категорию (например Компакт диски) в которой каждый второй товар будет бесплатным. Если товары Читать далее »

Шаблон вывода категорий woocommerce

Шаблон вывода категорий woocommerce

Зафиксировать шаблон (код) вывода категорий Woocommerce (я его назвал product-cat-list.php). Обычно я вывожу этот шаблон на стандартной странице /shop/ Шаблон вывода категорий Пересчет товаров во всех подкатегориях В шаблоне выше Читать далее »

Вкладка Дополнительная информация

Вкладка Дополнительная информация

У товаров WC есть вкладка Дополнительная информация (Additional Information), в которой по-умолчанию выводятся атрибуты, вес и габариты товара. Добавим в эту вкладку дополнительные данные. Проверки содержит ли товар атрибуты, вес Читать далее »

Добавить комментарий

16 комментариев

  1. Никита

    Случайная сортировка тоже работает некорректно. Если у вас одна страница с товарами, то проблем нет, но если страниц несколько, то на последующих страницах также происходит повторная сортировка, в результате чего товары могут повторяться

    1. Alexandr

      Спасибо! Учту этот момент.

  2. Андрей

    Куда добавляем? Где добавляем??? Какой файл?

  3. Денис

    Как сделать чтобы от меньшего в большему шли по цене? Настройки вуки не работают

    1. Alexandr

      Таким вопросом не задавался. т.к. сортировка по цене есть в базовой комплектации. А если она не работает, то нужно устранить причины этого (возможно какой-то плагин или кастомная функция).

  4. Dan Zakirov

    А как добавить сортировку по конкретному произвольному полю

    1. Alexandr

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

  5. Артем

    Подскажите пожалуйста! Как сделать чтоб была сортировка по «Распродажам»?

    1. Alexandr

      Принцип сортировки, как я понимаю, состоит в том чтобы сортировать по свойству которое есть у всех товаров. А «Распродажа» это специфическое состояние товара, т.е. наличие заполненного поля sale_price. Уверен что можно как-то придумать чтобы сначала выводились товары со скидками (я еще такого не делал), но не уверен что это удастся именно через сортировку.

  6. Алексей

    Вопрос немного в сторону, но может поможете…
    Можно сделать сортировку не выпадающим меню, а с помощью радио (input type=»radio»)?
    Вообще тупик… не могу нигде найти такой инфы…
    ну или может плагин какой так умеет?

    1. Alexandr

      Могу предположить, что Вам нужно в локальной папке шаблонов woocommerce изменить файл orderby/orderby.php, именно в нем создается данный фильтр. т.е. переделать тэг select и option на input type=»radio».
      Дополнение: попытался это сделать, но нужно также переопределить функцию/скрипт изменения поля и функцию select, без этого не работает. Где это делается не знаю.
      Дополнение 2: нашел нужный скрипт! Описал в статье как изменить select на radio кнопки. Способ 100% рабочий — проверил (по крайней мере на самой новой версии 4.0).

  7. Ed

    А как отсортировать цену по возрастанию, но что бы товары без цены или за ноль были в конце списка! 
    Пробовал вот этот код, он много где  в интернете есть, но не работает, товары вообще пропадают. 
    // Товары без цены или с ценой равной нулю будут в конце списка
    add_filter('posts_clauses', 'order_by_no_price', 50, 2);
    function order_by_no_price($posts_clauses) {
    global $wpdb;
    if (!is_admin() && is_woocommerce() && (is_shop() || is_product_category() || is_product_tag() || is_product_taxonomy())) {
    if($posts_clauses['join']!=' LEFT JOIN wp_wc_product_meta_lookup wc_product_meta_lookup ON wp_posts.ID = wc_product_meta_lookup.product_id '){
    $posts_clauses['join'] = $posts_clauses['join'] . " LEFT JOIN wp_wc_product_meta_lookup wc_product_meta_lookup ON wp_posts.ID = wc_product_meta_lookup.product_id ";
    }
    $posts_clauses['orderby'] = "wc_product_meta_lookup.min_price > 0 DESC, " . $posts_clauses['orderby'];
    }
    return $posts_clauses;
    }

    1. Alexandr

      Попробовал данный код. Но у меня он не также не работает — все товары исчезают. Я думаю, что нужно каким то образом переделывать сам фильтр сортировки price, но как это сделать сейчас не знаю. На будущее себе пометил.

  8. Нурик

    А подскажите пожалуйста, как можно сделать сортировку в алфавитном порядке???А Б В Г Д Е Ё Ж З ….. не хочу я 69баксов отдавать за фигню

    1. Alexandr

      В этой статье описан такой вариант сортировки — По названию. Вставляйте в файл functions.php

Варианты сортировки woocommerce
Апселлы и кросселы
Рекомендации для васАпселлы и кросселыOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.