Woocommerce. Показ товаров из выбранных категорий на главной странице магазина

·
Woocommerce. Показ товаров из выбранных категорий на главной странице магазина

Если вы любите Wordpress и вам нужно создать интернет-магазин, то, наверняка, вы в первую очередь подумали про Woocommerce.

Это идеальный плагин, который позволяет на блоговом движке сделать полноценный магазин. С фильтрами по настраиваемым атрибутам товаров, с разными шаблонами страниц, возможностью использовать скидки и купоны, миниатюрами для категорий товаров, возможностью редактирования таких опций, как наличие на складе, тарифы доставки и налога для отдельных товаров, видимость в каталоге, добавление подробных и кратких описаний. Это тот функционал, что вам доступен сразу после установки плагина. Так сказать, «из коробочки».

Еще плюс — огромное количество дополнительных плагинов, которые еще больше расширяют функционал woocommerce. Добавляют больше способов оплаты или доставки, подарочные сертификаты, слайдшоу на странице товара, дополнительные вкладки, фильтрацию товаров на основе Ajax, создание wish-листа, рейтинга или оригинального оформления атрибутов товаров и многое другое.

Кроме этого, продвинутые веб-дизайнеры знают, что очень многие возможности плагина невидимы через интерфейс административной панели wordpress, но заложены в коде woocommerce. И если понимать как, то эти возможности можно оттуда извлекать и подключать. В этом я сегодня еще раз убедился, что вам и продемонстрирую.

На самом деле, сниппетов для woocommerce написано достаточно много, самых разных. В работе над последним проектом мне пригодилось сразу несколько сниппетов:

  1. Возможность ограничить показ товаров в related products до товаров из одной категории.
  2. Возможность вывести атрибуты товаров как новую таксономию, чтоб их в дальнейшем можно было использовать в навигации на сайте (custom menu).
  3. Новый таб на странице одиночного товара для показа всех вложений к данному товару с определенным расширением (В частности, я подключал автоматический вывод в этом табе всех флешек, которые мы сконвертировали в формат html5).
  4. Сниппет для бесконечной прокрутки товаров (infinite scrolling).
  5. Два сниппета, чтобы разделить разбивку на страницы (pagination) и сортировку (ordering) и в дальнейшем вывести их в разных местах страницы каталога.

Если вам нужны любой из этих сниппетов, напишите в комментариях. Все эти сниппеты (кроме 3-го) я нашел на просторах интернета, поэтому тут моей заслуги нет никакой. Но мне понадобилась еще одна вещь, о которую я и споткнулся — как скрыть товары из определенных категорий на странице каталога?

Допустим, у вас есть магазин часов (на самом деле, я описываю конкретную ситуацию). В каталоге у вас есть сами часы, разбитые по категориям, а также разные сопутствующие товары — ремешки, подарочные карты, запчасти. Кроме этого, у вас есть отдельный раздел архивных часов, которые вы уже не продаете, но и удалять не хотите, потому что часы хорошие, интересные, и ваши покупатели любят иногда их посмотреть чисто для эстетического удовольствия. Естественно, что вы не хотите, чтобы архивные часы и какие-то другие подобные товары выводились на основной странице каталога, потому что это будет запутывать клиентов.

Проблема легко решается, если ваш каталог находится на одной из внутренних страниц — тогда вы просто создаете в меню новый пункт со ссылкой на категорию часов и называете его «магазин». А для других категорий создаете отдельные страницы.

Но если ваш магазин находится на главной странице? А так бывает в большинстве магазинов — сайт начинается с витрины. Здесь на помощь может прийти только специальный сниппет, который отфильтрует цикл на основе категорий товара и выведет только товары из нужных категорий. Причем выведет отфильтрованный цикл только на главной.

На поиски похожего сниппета убил несколько дней, перерыл всю документацию по woocommerce и околовукоммерческие сайты. Нашел сниппет, как скрыть категории с главной страницы, когда вы выводите в каталоге не товары, а категории (чувствуете разницу?). Но того, который мне был нужен, найти не смог. Понял, что придется писать самому.

Теперь попытаюсь воссоздать последовательность моих действий:

  1. Во-первых, нужно было найти, где же описана сама функция цикла продуктов. В файлах шаблонов она скрыта под вполне определенной переменной $woocommerce_loop. Но поиск по всем файлам плагина описания этой функции мне какого-то конкретного ответа не принес. Экспериментальным путем удалось установить, что искать нужно в файле /classes/class-wc-query.php
  2. Дальше пошли разные попытки написания функции, которая бы обращалась к таксономии product_cat, которая отвечает за категорию продукта. В качестве основы я взял функцию product_query( $q ) из вышеупомянутого файла. В итоге, пришел к чему-то вроде вот такого кода:
    $q->set( 'tax_query', array(array(
    'taxonomy' => 'product_cat',
    'field' => 'slug',
    'terms' => array( 'collections' ),
    'operator' => 'IN'
    )));
  3. Теперь этот код надо как-то заставить работать. Функция product_query( $q) позволяет подключаться к ней напрямую через do_action
    do_action( 'woocommerce_product_query', $q, $this );

    Соответственно, как мы можем прочитать из описания данной функции, она исполняет хук, созданный с помощью функции add_action. Соответственно, чтобы было, что исполнять, надо этот хук создать. Получается что-то вроде:

    function product_shop( $q ) {
    
    $q->set( 'tax_query', array(array(
    'taxonomy' => 'product_cat',
    'field' => 'slug',
    'terms' => array( 'collections' ),
    'operator' => 'IN'
    )));
    
    }
    add_action( 'woocommerce_product_query', 'product_shop', 10, 2 );

    То есть, мы создали функцию, которая делает выборку из списка продуктов на основе нужной нам категории, а потом мы эту функцию подключаем к циклу продуктов через хук add_action к функции do_action, милостиво предоставленной нам woocommerce. Можно сделать и наоборот — в функции описать не те категории, которые надо выводить на главной, а те, которые надо скрыть. Для этого достаточно поменять оператор с «In» на «Not In». Естественно, что сами категории, а точнее, их slug, прописываете через запятую в массиве «terms».

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

    что, в принципе, не будет неправильным. Но если вы внимательно изучили файл /classes/class-wc-query.php, то напишите условие немного по-другому:

    if ( $q->is_post_type_archive() )

    а еще лучше вот так:

    if ( !$q->is_post_type_archive() ) return;

    В итоге, мы получаем вот такой симпатичный (а главное, рабочий!) код, который нужно вставить в файл funcion.php вашего шаблона:

    function product_shop( $q ) {
    
    if ( !$q->is_post_type_archive() ) return;
    $q->set( 'tax_query', array(array(
    'taxonomy' => 'product_cat',
    'field' => 'slug',
    'terms' => array( 'collections' ),
    'operator' => 'IN'
    )));
    
    }
    add_action( 'woocommerce_product_query', 'product_shop', 10, 2 );

Надеюсь, что вам понравился этот пост. В будущем планирую продолжить разговор об использовании woocommerce и приемах работы с ним.

Обновление от 6 февраля 2017 года:

Для более быстрой работы данного сниппета можно подключать его не к хуку woocommerce_product_query, а к хуку pre_get_posts, то есть, получается вот такой сниппет в итоге:

add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );

function custom_pre_get_posts_query( $q ) {

	if ( ! $q->is_main_query() ) return;
	if ( ! is_admin() && is_shop()) {

		$q->set( 'tax_query', array(array(
			'taxonomy' => 'product_cat',
			'field' => 'slug',
			'terms' => array( 'collections', 'gift-cards' ), // Don't display products in the archive category on the shop page
			'operator' => 'NOT IN'
		)));

	}
	remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}

В данном сниппете я, для примера, указал еще несколько опций:

  1. if ( ! is_admin() && is_shop()) {

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

  2. 'operator' => 'NOT IN'

    — Здесь можно указать как ‘IN’, так и ‘NOT IN’ — последнее означает, что мы исключаем категории со страницы магазина.

Очень важный момент: данный сниппет ломает работу фильтров по атрибутам! Если вы используете данный сниппет и используете в боковой колонке на главной вашего сайта фильтры по атрибутам (Woocommerce Layered Nav Widget), то они у вас работать не будут. Это не баг woocommerce, это просто данный сниппет не работает с фильтрами. Пока не знаю, как можно это обойти.

Поделиться записью:
Агентство Romapad
Агентство Romapad
Работаем с 2009 года. Реализовано более 400 проектов. Слаженная команда профессионалов. Создание и администрирование сайтов. Техническая поддержка. Помощь новичкам.
Подпишитесь на рассылку новостей
Отправляя заявку, вы даете согласие на обработку персональных данных
Комментарии к публикациям
Похожие статьи
Прокрутить вверх
Оставьте Ваши контакты,
и мы с Вами свяжемся

Отправляя заявку, вы даете согласие на
обработку персональных данных
Заявка отправлена!
Ожидайте звонка менеджера.

Nullam quis risus eget urna mollis ornare vel eu leo. Aenean lacinia bibendum nulla sed 

Join our newsletter and get 20% discount
Promotion nulla vitae elit libero a pharetra augue