Сортировка по произвольному полю (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 без плагинов.

<?php
$big = 999999999;
echo $pagination = paginate_links([
    'base'      => str_replace($big, '%#%', get_pagenum_link($big)),
    'format'    => '',
    'current'   => max(1, get_query_var('paged')),
    'total'     => $query->max_num_pages,
    'type'      => 'list',
    'prev_text' => '',
    'next_text' => '',
]);

wp_reset_postdata();
?>

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

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

При отправке формы и перезагрузке страницы мы увидим хвосты в 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();
})

Может пригодиться

Админ admin