Фильтры в интернет-магазине. Урок 2. Структура проекта и верстка
Переходим ко второй части наших уроков. Здесь рассмотрим структуру проекта, его файлов и папок, сверстаем блоки с фильтрами, товарами и подключим плагин jQueryUI.slider для регулировки цен.
Структура файлов и папок
Те, кто читал мои предыдущие статьи про корзину и отправку заказа, ничего нового не увидят. Если Вы с этими постами не знакомы, то кратко структура представляется так.
В корне проекта лежит файл catalog.html, который содержит базовую верстку и подключает стили и скрипты. В папку js/modules положим файл catalogDB.js. Суффикс «DB» — от database, чтобы отличать модуль с фильтрами, работающий с БД, от первого модуля каталога, рассмотренного в статье про корзину.
В файле js/modules/main.js подключаются и инициализируются все модули, в том числе и наш новый catalogDB. Для его подключения в main.js нужно будет написать пару строк.
В файле css/main.css находятся немногочисленные стили. В целом, мы вполне обойдемся и bootstrap.
В папку scripts закинем файл catalog.php, который будет выполнять всю серверную работу.
И последнее — в качестве элемента управления для регулирования цен мы воспользуемся готовым решением от jQueryUI, а именно компонентом slider. Создадим отдельную папку в корне components, в ней папку jquery-ui и закинем в нее все файлы, имеющие отношение к компоненту slider.
А теперь последовательно.
Базовый файл catalog.html
Секция head ничем не отличается от других страниц нашего магазина. Для body навесим атрибут data-page=»catalogDB» (это по аналогии с предыдущими страницами, чтобы отличать их друг от друга). Содержимое body будет простым.
Webdevkin. Интернет-магазин. Фильтры в каталоге
- Каталог
- Каталог с фильтрами
- Корзина
- Оформление заказа
// Здесь будут фильтры
Пока ничего хитрого. Заголовок h2, меню nav nav-pills и два контейнера для фильтров и списка товаров. Ими мы займемся чуть позже. В списке товаров будет крутиться гифка до тех пор, пока не загрузятся данные с сервера.
В конце перед закрывающимся тегом body подключаем 5 javascript-файлов: jQuery, underscore, наш новый модуль catalogDB, старую добрую корзину и main.js — главный модуль приложения, который запускает все остальное. Подробнее эти модули расписаны в статье Корзина для интернет-магазина на фронте.
Заготовка модуля catalogDB.js
Сильно мудрить не будем и пойдем по стопам и примерам предыдущих статей. Объявим модуль-переменную catalogDB и заведем в ней пока единственную функцию init, которую экспортируем во внешний мир. В init будет для начала строчка вывода в консоль соответствующего сообщения. Дальше, конечно же, ее расширим.
'use strict'; // Модуль каталога для работы с БД var catalogDB = (function($) < // Инициализация модуля function init() < console.info('init catalogDB'); >// Экспортируем наружу return < init: init >>)(jQuery);
Редактируем главный модуль main.js
Напоминаю, в main.js у нас находится модуль app — главный модуль приложения. И его метод init, который и выполняет всю работу по инициализации соответствующих частей приложения. Чтобы завести наш новый catalogDB, нужно дописать метод init в main.js вот так:
function init() < if (page === 'catalog') < catalog.init(); cart.init(optionsCatalog); >// --- Новый код if (page === 'catalogDB') < catalogDB.init(); cart.init(optionsCatalog); >// --- Новый код if (page === 'cart') < cart.init(optionsCart); >if (page === 'order') < order.init(); cart.init(optionsOrder); >>
Мы просто запускаем catalogDB.init и инициализируем корзину с настройками, как на самой первой странице каталога.

Если все сделали правильно, то увидите примерно такую картину
Верстаем панель фильтров
Для начала добавим контейнерам filters и goods бутстраповские классы col-md-12, дабы они занимали всю доступную ширину. И добавим между ними парочку переносов строк, если прямо сейчас не хотим возиться с css.
А в filters уже напишем основную верстку
Верстка стандартная, на что стоит обратить внимание, так это на id, data-атрибуты, классы c js-префиксом и атрибуты name. Все эти данные будут использоваться в дальнейшем в js-коде или участовать в формировании данных для отправки на сервер (как атрибуты name).

Понятно, что пока все данные захардкожены. Категории, бренды и цены будут подтягиваться с сервера и выглядеть прилично. Я сознательно подготовил сначала всю верстку, чтобы потом не отвлекаться на нее при разработке js-кода. А пока это выглядит так
Как Вы могли заметить, вместо обещанного слайдера для цен стоят обычные числа, разделенные обычными дефисом. Сейчас мы это исправим.
Подключаем слайдер jqueryUI
Для подключения слайдера нам понадобится немногое — скачать нужные файлы с официального сайта и закинуть их в папку проекта. Вот ссылка на используемый в нашей статье компонент. В скачанном плагине будет по одному css и js файлу и папку images с иконками. Создадим в корне нашего проекта папку components, а в ней jquery-ui, куда и положим скачанные файлы. А теперь заставим все это добро работать.
Сначала подключим на странице каталога catalog.html два нужных файла — components/jquery-ui/jquery-ui.min.css в секции head и components/jquery-ui/jquery-ui.min.js — среди скриптов в конце страницы. Только js подключайте обязательно после jquery и до catalogDB.
Ну и самое интересное — js-код для инициализации слайдера. Модуль catalogDB.js будет выглядеть так:
'use strict'; // Модуль каталога для работы с БД var catalogDB = (function($) < var ui = < $prices: $('#prices'), $pricesLabel: $('#prices-label'), $minPrice: $('#min-price'), $maxPrice: $('#max-price') >; // Инициализация модуля function init() < _initPrices(< minPrice: 5000, maxPrice: 50000 >); > // Изменение диапазона цен function _onSlidePrices(event, elem) < var minPrice = elem.values[0], maxPrice = elem.values[1]; ui.$pricesLabel.html(minPrice + ' - ' + maxPrice + ' руб.'); ui.$minPrice.val(minPrice); ui.$maxPrice.val(maxPrice); >// Инициализация цен с помощью jqueryUI function _initPrices(options) < ui.$prices.slider(< range: true, min: options.minPrice, max: options.maxPrice, values: [options.minPrice, options.maxPrice], slide: _onSlidePrices >); > // Экспортируем наружу return < init: init >>)(jQuery);
Для начала создадим объект ui, в котором закешируем нужные dom-элементы.
_initPrices выполняет саму инициализацию слайдера (взято из документации jqueryUI). В параметре options мы передаем минимальное и максимальное значение для слайдера. Опция slide содержит функцию _onSlidePrices, вызываемую при изменении позиций слайдера. В _onSlidePrices пишем код, который перерисовывает метку с указанием диапазона цен и устанавливает значения для скрытых инпутов min-price и max-price. А в методе init мы просто запустим _initPrices с левыми настройками 5000 и 50000.

Слайдер подключен, можете поиграть с ним и наблюдать, как меняются значения цен
Пора бы уже и заканчивать с версткой и переходить к более интересным вещам, но нам осталось еще совсем немного — заделать список товаров. Утешает то, что после этого к верстке мы уже не вернемся 🙂
Верстаем список товаров
Товары у нас будут очень похожи на уже упоминаемый каталог из статьи про корзину в интернет-магазине. Разве что чуть компактнее для экономии места. Добавим в разметку верстку для одного товара. Смотрим html-код.
Артикул 12, Acer AspireБренд: Acer18000 руб.
data-атрибуты ровно такие же, какие и нужны для возможности добавления товаров в корзину. Картинки для всех товаров Вы найдете в исходниках (ссылка будет после публикации всех уроков). И последним штрихом добавим немного css-кода в файл css/main.css. Необязательно, но для небольшой красоты пусть будет.
/* Каталог товаров с фильтрами*/ .small-good-item < border: solid 1px gray; padding: 5px; list-style: none; border-radius: 2px; >.small-good-item__img < max-width: 60%; >.small-good-item__name < color: steelblue; >.small-good-item__price

Наконец наша верстка полностью готова, результат видим ниже
Подведем итоги
На этом уроке мы сверстали весь интерфейс фильтров и товаров нашего интернет-магазина, практически не написав свои стили. Этим мне и нравятся фреймворки вроде bootstrap, которые позволяют быстро накидать прототип страницы, довольно простой, но притом не самый страшный.
Верстать нам больше не придется, следующий урок будет о том, как собрать все нужные данные на клиенте, как отправить их на сервер и вернуть какой-то результат. А пока можете вспомнить предыдущий урок про структуру базы данных. Она нам еще пригодится при написании серверного кода.
Все об интернет-магазинах
- Демо интернет-магазина
- Корзина интернет-магазина. С чего все началось
- Оформляем заказ на клиенте и сервере
- Добавляем доставку
- Фильтры и сортировки на клиенте и сервере
- Урок 0. Вводный
- Урок 1. Структура базы данных
- Урок 2. Структура проекта и верстка
- Урок 3. Сбор данных на клиенте и отправка на сервер
- Урок 4. Пишем базовый php-код и sql-запросы
- Урок 5. Прием данных с сервера и рендеринг на клиенте
- Урок 6. Заключительный, дорабатываем некоторые штрихи
- Сравнение товаров
- Постраничная навигация по товарам
- Преобразуем каталог, переключаем внешний вид товаров одной кнопкой
- Отправка sms при оформлении заказа
- Админка интернет-магазина на vue.js — серия уроков
- Авторизация на сессиях. Делаем логин в админке
- Docker для начинающих. Докеризуем интернет-магазин
Заходите в группу в контакте — https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как реализовать простой фильтр товаров?
Есть левый сайт бар и контентная часть.
1. Как только мы попадаем на страницу у нас отображается список товаров, он ограничек кол-вом, например 10. (можно список из 10 последних добавленных).
2. В сайд баре расположены категории товаров. Нажимаем на категорию и в контентной части отображаются товары из этой категории, но уже все (или к примеру не более 50).
3.А сама ссылка в сайтбаре расскрывается на подкатегории, с которыми мы можем проделать тоже самое.
Как такое чудо можно реализовать, в jq и js не силен, но разобраться смогу. Сайт давольно простой, каких то супер крутых новаротов не нужны. Хочу все это сделать на клиентской стороне, без использования сервера.

- Вопрос задан более трёх лет назад
- 4804 просмотра
Комментировать
Решения вопроса 2

программист-велосипедист
Обычно фильтры — это AJAX запрос к контроллеру ( обработчеку всего это добра ) с уточняющим параметром, тот в свою очередь делает подзапрос в базу данных. Получает ответ , отдаёт на страницу , JS перерисовывает область товаров и вуаля. Фильтр сработал.
Хочу все это сделать на клиентской стороне, без использования сервера.
для этого надо выгружать все товары на страницу , потом прятать по категории, потом показывать . что не есть гуд
Ответ написан более трёх лет назад
Нравится 1 3 комментария
Novamoscow @Novamoscow Автор вопроса
На сколько сложно реализовать предложенный метод ? Я делаю 3 — 4 сайт, с сервером ни разу не работал.
Novamoscow @Novamoscow Автор вопроса
еще такой вопрос, я как верстальщик, на какой стадии все это должен оставить? Я так понимаю, мне нужно только алгоритм связи с сервером написать, чтобы сайт отдавал запрос в базу и принимал его ( ну и отрисовка результата)

Novamoscow: если опыт нету, то сложно. Делается это после того, как будет написан обработчик ajax запросов. Т.е. область ответственности верстальщика заканчивается на клиенте.

Сергей delphinpro @delphinpro Куратор тега CSS
frontend developer
Нельзя это сделать только на клиенте. Если конечно у вас не 10-20-30 товаров всего.
В реальном магазине сотни, а то и тысячи товаров. Все их на страницу вы не загрузите (ну вы-то может и загрузите, только ни один пользователь не будет ждать пока загрузится эта ваша мега-страница).
А значит фильтр должен отправлять запросы на сервер, получать от него список товаров, соответствующих фильтру и показывать их.
Вам, как верстальщику, разумеется, не нужно бросаться писать серверные скрипты, с этим штатный программист прекрасно справится (да и не пустит он вас на свою территорию =)). А вот что от вас нужно — это написать на js весь интерактив фильтра, отправку запроса с параметрами, получение ответа и рендеринг сетки товаров. Формат запросов-ответов нужно обсудить с программистом. Как именовать параметры, в каком формате он будет отдавать данные (json/html).
Для верстки и отладки (для себя) можно самому написать простенький php скриптик-заглушку, который будет реагировать на пару фильтров и отдавать несколько тестовых товаров. Или воспользоваться dev-сервером проекта, если он есть.
Создание компонента фильтра данных на чистом CSS
От автора: в этом руководстве мы узнаем о создании компонента фильтра данных на чистом CSS, для которого не требуется JavaScript. Мы будем использовать простую разметку, некоторые элементы управления формой и некоторые действительно интересные селекторы CSS, которые вы, возможно, раньше не использовали.
Над чем мы работаем
У каждого автора здесь на Tuts + есть собственная страница архива. Мы собираемся воссоздать такой список руководств, используя собственную разметку. Затем мы реализуем компонент, который будет фильтровать записи на основе категорий, к которым они принадлежат. Вот наш окончательный проект:
Давайте построим его!
1. Начинаем с HTML-разметки
Мы начнем с определения категорий фильтров в нашем компоненте. В этом примере мы будем использовать семь фильтров:
Для этого мы сначала определяем семь переключателей, которые группируем через ключевое словом categories. По умолчанию выбрана первая кнопка-переключатель:
Затем мы создаем упорядоченный список, который содержит метки, связанные с этими переключателями. Помните, что мы связываем переключатель с меткой, устанавливая его значение id равным значению for метки:
< label for = "JavaScript" >JavaScript < / label >
< label for = "fullPage.js" >fullPage . js < / label >
Затем мы настраиваем другой упорядоченный список, включающий элементы, которые мы хотим фильтровать (наши карточки). Каждый из отфильтрованных элементов будет иметь собственный атрибут data-category, значение которого представляет собой список фильтров, разделенных пробелами:
В нашем случае фильтруемые элементы будут постами. Таким образом, разметка, которую мы будем использовать для описания поста вместе с его мета-данными (заголовок, изображение, категории), выглядит следующим образом:
Когда разметка готова, давайте обратим внимание на необходимые стили.
2. Определение стилей
Сначала мы визуально скрываем переключатели:
input[type=»radio»] < position : absolute ; left : -9999px ;
Затем мы добавляем несколько стилей для фильтров:
—black : #1a1a1a ;
—white : #fff ;
—green : #49b293 ;
text-align : center ;
margin-bottom : 2rem ;
display : inline-block ;
.filters label <
padding : 0.5rem 1rem ;
margin-bottom : 0.25rem ;
border-radius : 2rem ;
min-width : 50px ;
line-height : normal ;
cursor : pointer ;
transition : all 0.1s ;
.filters label:hover <
background : var ( --green ) ;
color : var ( --white ) ;
CSS Grid Layout
Далее мы укажем некоторые стили для фильтруемых элементов. Самое главное, мы используем CSS Grid, чтобы уложить их по-разному в зависимости от размера экрана:
—black : #1a1a1a ;
—white : #fff ;
—green : #49b293 ;
display : grid ;
grid-gap : 1.5rem ;
grid-template-columns : repeat ( 4, 1fr ) ;
.posts .post <
background : #fafafa ;
border : 1px solid rgba ( 0, 0, 0, 0.1 ) ;
.posts .post-title <
font-size : 1.3rem ;
.posts .post-title:hover <
text-decoration : underline ;
.posts figcaption <
padding : 1rem ;
.posts .post-categories <
margin-bottom : 0.75rem ;
font-size : .75rem ;
.posts .post-categories * <
display : inline-block ;
.posts .post-categories li <
margin-bottom : 0.2rem ;
.posts .post-categories a <
padding : 0.2rem 0.5rem ;
border-radius : 1rem ;
border : 1px solid ;
line-height : normal ;
background : all 0.1s ;
.posts .post-categories a:hover <
background : var ( --green ) ;
color : var ( --white ) ;
@media screen and (max-width: 900px) <
grid-template-columns : repeat ( 3, 1fr ) ;
@media screen and (max-width: 650px) <
grid-template-columns : repeat ( 2, 1fr ) ;
Примечание. Для удобства чтения мы не группируем в CSS общие правила.
Добавление стилей фильтрации
Идея здесь удивительно проста. Каждый раз, когда мы нажимаем на фильтр, должны отображаться только соответствующие отфильтрованные элементы (посты). Для реализации этого функционала мы будем использовать комбинацию следующих вещей:
Обратный псевдо-класс ( :not())
Общий комбинатор элементов одного уровня ( ~) переименованный в CSS4 в «последовательно-одноуровневый селектор»
Когда мы нажимаем на фильтр «All», отображаются все посты, имеющие атрибут data-category:
[value=»All»]:checked ~ .posts [data-category] < display : block ;
Когда мы нажимаем на любую другую категорию фильтра, будут видны только целевые посты:
[value=»CSS»]:checked ~ .posts .post:not([data-category~=»CSS»]),
[value=»JavaScript»]:checked ~ .posts .post:not([data-category~=»JavaScript»]),
[value=»jQuery»]:checked ~ .posts .post:not([data-category~=»jQuery»]),
[value=»WordPress»]:checked ~ .posts .post:not([data-category~=»WordPress»]),
[value=»Slider»]:checked ~ .posts .post:not([data-category~=»Slider»]),
[value=»fullPage.js»]:checked ~ .posts .post:not([data-category~=»fullPage.js»]) <
display : none ;
Например, когда мы нажимаем на категорию фильтра «Slider «, будут отображаться только посты, принадлежащие этой категории.

Компонент фильтра на чистом CSS в действии
Стоит отметить, что в приведенных выше стилях вместо синтаксиса [att~=val] мы могли бы в равной степени использовать синтаксис [att*=val]. Вот как будет выглядеть это изменение:
[value=»CSS»]:checked ~ .posts .post:not([data-category*=»CSS»]),
[value=»JavaScript»]:checked ~ .posts .post:not([data-category*=»JavaScript»]),
[value=»jQuery»]:checked ~ .posts .post:not([data-category*=»jQuery»]),
[value=»WordPress»]:checked ~ .posts .post:not([data-category*=»WordPress»]),
[value=»Slider»]:checked ~ .posts .post:not([data-category*=»Slider»]),
[value=»fullPage.js»]:checked ~ .posts .post:not([data-category*=»fullPage.js»]) <
display : none ;
Быстрое пояснение CSS-селектора
Что именно указывает этот селектор? Первая часть [value=»CSS»]:checked ищет выбранные переключатели с определенным значением (в данном случае «CSS»).
После этого тильда (~) — это то, что мы сейчас называем «последовательно-одноуровневым селектором». Он выбирает элементы, у которых тот же родительский элемент, что и у предыдущего элемента, даже если они в разметке расположены не рядом. Так что ~ .posts .post ищет элементы, .posts .post, у которых тот же родительский элемент, что и у выбранного переключателя.
Чтобы еще повысить специфичность, мы уточняем наш селектор :not([data-category~=»CSS»]), чтобы он выбирал только те элементы .post, у которых атрибут data-category не содержит значение «CSS» где-то внутри разделенного пробелами списка.
Затем он применяет display: none; к любым элементам, которые соответствуют этим критериям. Это довольно сложный селектор, хотя он вполне логичен. Человеческим языком вы можете описать это как: «Когда выбран переключатель со значением«CSS», найти все элементы, которые не содержат «CSS» в списке категорий данных, и скрыть их».
Завершающие стили
В качестве последнего шага мы добавим правило, которое выделяет активную категорию фильтра:
Добавление на сайт AJAX фильтра постов по категориям, произвольным полям, либо по дате. Сортировка по убыванию / возрастанию.
Сейчас я покажу вам, как легко и просто создавать асинхронные фильтры записей/товаров (и те и вторые — это произвольные типы постов) на сайте при помощи всего лишь jQuery и WP_Query.
Для простоты не буду загружать пост ничем лишнем — рассмотрю только фильтрацию массива аргументов, постраничной навигации не будет, чтобы не усложнять пример.
А теперь давайте приступим к нашему уроку. По шагам.
Шаг 1. HTML фильтра для сайта
Форма будет состоять из:
- выпадающего списка таксономий (для простоты — рубрик),
- диапазона значений произвольного поля (например пусть это будет цена),
- радио-кнопок сортировки по дате, по убыванию и возрастанию,
- а также чекбокса, который позволит отфильтровать посты, отобразив только те из них, у которых имеется миниатюра.
1.1 Добавляем список из рубрик/таксономий
Неважно, элементы какой таксономии вы хотите вывести, в любых случаях функция get_terms() мне кажется ну самым удобным вариантом.
Для того, чтобы вывести элемент выпадающего списка с её помощью, вы можете воспользоваться следующим кодом:
if( $terms = get_terms( array( 'taxonomy' => 'category', 'orderby' => 'name' ) ) : // как я уже говорил, для простоты возьму рубрики category, но get_terms() позволяет работать с любой таксономией echo '; foreach ( $terms as $term ) { echo ' ->term_id . '">' . $term->name . ''; // в качестве value я взял ID рубрики } echo ''; endif;
1.2 Произвольные поля
Для примера возьмём минимальную и максимальную цену.
Ну тут всё легко, можно просто использовать два HTML-инпута. Конечно, будет гораздо интереснее элемент range с возможностью передвигания ползунков минимального и максимального значения. Но это уже на ваше усмотрение, плагинов jQuery много, что-нибудь да выберете.
echo ''; echo '';
1.3 Дата
Как я уже писал выше — это будут две radio-кнопки.
echo ''; echo '';
1.4 Чекбокс «Только с фото»
Ну тут вообще всё просто.
echo '';
1.5 HTML-форма фильтра целиком
echo '// категории if( $terms = get_terms( array( 'taxonomy' => 'category', 'orderby' => 'name' ) ) ) { // как я уже говорил, для простоты возьму рубрики category, но get_terms() позволяет работать с любой таксономией echo '; foreach ( $terms as $term ) { echo ' ->term_id . '">' . $term->name . ''; // в качестве value я взял ID рубрики } echo ''; } // минимальная/максимальная цена echo ''; echo ''; // дата по возрастанию/убыванию echo ''; echo ''; // чекбокс только с фото echo ''; echo ' ';
Что делать с этим кодом?
Тут всё зависит от задачи, которая перед вами стоит. Например я могу создать какой-то шаблон страницы, в котором будут выводиться посты без фильтрации и присутствовать код фильтра, либо например сделать то же самое на странице блога, шаблон home.php или index.php (подробнее про шаблоны – тут). Ну или же можете посмотреть видео в конце урока.
Шаг 2. JavaScript (jQuery) скрипт для отправки запроса и получения данных
2.1 Подключение скриптов
Прежде, чем предлагать вам готовый jQuery-код, я бы хотел поговорить о том, как его подключить и куда вставить код в целом.
Во-первых, давайте в папке с темой создадим любой файл .js , пока пустой, например я могу создать filter.js .
Во-вторых, давайте подключим наш файл скрипта и сам jQuery функцией wp_enqueue_script() и wp_register_script(). Это можно сделать так:
add_action( 'wp_enqueue_scripts', 'truemisha_jquery_scripts' ); function truemisha_jquery_scripts() { wp_enqueue_script( 'jquery' ); wp_register_script( 'filter', get_stylesheet_directory_uri() . '/filter.js', array( 'jquery' ), time(), true ); wp_enqueue_script( 'filter' ); }
Можете закинуть в файл filter.js строчку jQuery( function( $ ) < alert( 'test' ); >, чтобы убедиться, что всё работает.
В-третьих, нам нужно получить URL обработчика AJAX в WordPress, это правильнеее всего делать через wp_localize_script(), в итоге в коде выше мы добавляем одну строчку:
wp_localize_script( 'filter', 'true_obj', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
2.2 Сам код отправки запроса
Смело отправляем его в файл filter.js .
jQuery( function( $ ){ $( '#filter' ).submit(function(){ var filter = $(this); $.ajax({ url : true_obj.ajaxurl, // обработчик data : filter.serialize(), // данные type : 'POST', // тип запроса beforeSend : function( xhr ){ filter.find( 'button' ).text( 'Загружаю. ' ); // изменяем текст кнопки }, success : function( data ){ filter.find( 'button' ).text( 'Применить фильтр' ); // возвращаеи текст кнопки $( '#response' ).html(data); } }); return false; }); });
Шаг 3. Обработчик PHP
Этот код можете вставить в файл functions.php например или читайте этот гайд.
Основная задача, с которой у многих людей возникают трудности — это определение аргументов для WP_Query с учётом всех параметров из фильтра выше.
add_action( 'wp_ajax_myfilter', 'true_filter_function' ); add_action( 'wp_ajax_nopriv_myfilter', 'true_filter_function' ); function true_filter_function(){ $args = array( 'orderby' => 'date', // сортировка по дате у нас будет в любом случае (но вы можете изменить/доработать это) 'order' => $_POST[ 'date' ] // ASC или DESC ); // для таксономий if( isset( $_POST[ 'categoryfilter' ] ) ) { $args[ 'tax_query' ] = array( array( 'taxonomy' => 'category', 'field' => 'id', 'terms' => $_POST[ 'categoryfilter' ] ) ); } // создаём массив $args[ 'meta_query' ] если указана хотя бы одна цена или отмечен чекбокс if( isset( $_POST[ 'cena_min' ] ) || isset( $_POST[ 'cena_max' ] ) || isset( $_POST[ 'featured_image' ] ) && 'on' == $_POST[ 'featured_image' ] ) { $args[ 'meta_query' ] = array( 'relation' => 'AND' ); } // условие 1: цена больше $_POST[ 'cena_min' ] if( isset( $_POST[ 'cena_min' ] ) ) { $args[ 'meta_query' ][] = array( 'key' => 'cena', 'value' => $_POST[ 'cena_min' ], 'type' => 'numeric', 'compare' => '>' ); } // условие 2: цена меньше $_POST[ 'cena_max' ] if( isset( $_POST[ 'cena_max' ] ) ) { $args[ 'meta_query' ][] = array( 'key' => 'cena', 'value' => $_POST[ 'cena_max' ], 'type' => 'numeric', 'compare' => ' ); } // условие 3: миниатюра имеется if( isset( $_POST[ 'featured_image' ] ) && 'on' == $_POST[ 'featured_image' ] ) { $args[ 'meta_query' ][] = array( 'key' => '_thumbnail_id', 'compare' => 'EXISTS' ); } query_posts( $args ); if ( have_posts() ) { while ( have_posts() ) : the_post(); // тут вывод шаблона поста, например через get_template_part() echo ' . get_permalink() . '">' . get_the_title() . ''; endwhile; } else { echo 'Ничего не найдено'; } die(); }
Пара комментариев по коду:
- Подробно про параметр tax_query (строки 13-19) можете почитать здесь.
- Про meta_query у меня вообще есть отдельный урок.
Купить курс
- 7 видеоуроков
- Доступ к теме курса с готовым кодом после каждого урока
- Единоразовый платёж
- Доступ навсегда
- Уроки актуальны в 2023-м году
