Сортировка по произвольному полю (WordPress)

Рассмотрим, как отсортировать по произвольному полю (ACF) в WordPress. Для примера будем использовать select, но здесь нет разницы какие элементы форм использовать.

Какие шаги необходимо предпринять:

  1. создание произвольного поля в ACF;
  2. HTML структура;
  3. вывод товаров;
  4. доработка формы фильтра
  5. вывод товаров для текущей сортировки.
  6. отправка формы при выборе option.

Создание произвольного поля

Пусть произвольное поле будет цена — будем сортировать по нему (по возрастанию и убыванию).

Создание произвольного поля ACF

HTML-разметка фильтра сортировки

Начнём с простой HTML-разметки, далее сделаем её динамической, т.е. будем проверять какой тип сортировки в текущий момент выбран.

<form class="sorting_form">
    <select name="sorting" class="sorting_select">
        <option value="ASC" selected>Сначала дешёвые</option>
        <option value="DESC">>Сначала дорогие</option>
    </select>
    <button type="button">Фильтровать</button>
</form>

Вывод товаров

Пусть у нас есть таксономия «Товары» my_product и таксономия «Категории товаров» my_product_category.

Выведем товары с сортировкой по умолчанию (ASC). Для упрощения, как уже говорил выше, после того как у нас всё выведется по умолчанию, только тогда мы добавим динамики.

<?php
global $wp_query;
$tax_name = "my_product_category";
$tax_terms = get_terms($tax_name, "hide_empty=1");
$paged = (get_query_var("paged")) ? get_query_var("paged") : 1;

$query = new WP_Query(array(
    "post_type"      => "my_product",
    "posts_per_page" => get_option("posts_per_page"),
    "paged"          => $paged,
    "taxonomy"       => $tax_name,
    "meta_key"       => "price",           # поле ACF
    "orderby"        => "meta_value_num",
    "order"          => ASC                # Сначала дешёвые
));

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        get_template_part("/template-parts/loop-template");
    }
} else echo "<p>Нет товаров в данной категории.</p>";
?>

Обратите внимание, мы сортируем по произвольному полю ACF price.

Пагинация. Более подробно о создании пагинации можно прочитать в этой статье — Пагинация в WordPress без плагинов.

Доработка формы фильтра

Если все вышеописанные шаги у вас не вызвали проблем и всё успешно работает, добавим динамики.

При отправке формы и перезагрузке страницы мы увидим хвосты в URL — GET-параметры. Будем добавлять атрибут checked выбранному select option:

<select name="sorting" class="sorting_select">
    <option value="ASC" <?= ($_GET["sort"] == "ASC") ? "selected" : ""; ?>>Сначала дешёвые</option>
    <option value="DESC" <?= ($_GET["sort"] == "DESC") ? "selected" : ""; ?>>Сначала дорогие</option>
</select>

Вывод товаров для выбранной сортировки

Осталось получить и добавить текущее значение сортировки в запрос WP_Query.

if ($_GET["sorting"]) {
    $sorting = $_GET["sorting"];
} else { // по умолчанию
    $sorting = "ASC";
}

$query = new WP_Query(array(
    "post_type"      => "solutions",
    "posts_per_page" => get_option("posts_per_page"),
    "paged"          => $paged,
    "taxonomy"       => $tax_name,
    "meta_key"       => "price", # поле ACF
    "orderby"        => "meta_value_num",
    "order"          => $sorting
));

Отправка формы при выборе option

Можно добавить автоматическую отправку формы при выборе какого-либо option:

const form = document.querySelector(".sorting_form");
const select = document.querySelector(".sorting_select");

select.addEventListener("change", function () {
    form.submit();
})

На этом на сегодня всё. Может пригодиться: