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

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

HIT

11.03.2017

16146

14

Добавляем свои варианты сортировки в 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);

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

  • Похожие записи
  • Комментарии
  • Вложения
Поле для вариативного товара

Поле для вариативного товара

Как делать произвольные (пользовательские) поля для товаров Woocommerce описано здесь. Но теперь пойдем дальше — сделаем поле для вариативного товара. Это должно открыть горизонты для интересных решений. Но я предвижу Читать далее »

Фильтры Woocommerce

Фильтры Woocommerce

В базовую комплектацию Woocommerce входит набор виджетов для фильтрации товаров. Но данные виджеты необходимо несколько доработать. WooCommerce Навигация по слоям В этом виджете необходимо задать атрибут товара по которому будет Читать далее »

/ /
Единица измерения товара

Единица измерения товара

В связи с растущими потребностями к функционалу интернет-магазинов будем создавать востребованный функционал на базе плагина Woocommerce. Единица измерения товара Если необходимо выводить единицу товара (шт, кв.м, упаковка, пог.м, и т.д.), Читать далее »

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

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

  1. Аватар
    Никита

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

    1. Alexandr
      Alexandr

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

  2. Аватар
    Андрей

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

  3. Аватар
    Денис

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

    1. Alexandr
      Alexandr

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

  4. Аватар
    Dan Zakirov

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

    1. Alexandr
      Alexandr

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

  5. Аватар
    Артем

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

    1. Alexandr
      Alexandr

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

  6. Аватар
    Алексей

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

    1. Alexandr
      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
      Alexandr

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

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