Множественная фильтрация тегов облака

Вопрос или проблема

Я пишу плагин, который создает пользовательский тип записи и два связанных пользовательских таксономии. Страница списка/архива пользовательского типа записи должна быть фильтруемой по терминам в одной или обеих таксономиях, т.е. не просто фильтр по одному термину таксономии. Фильтры должны отображаться как два отдельных облака тегов.

У кого-нибудь есть опыт реализации этой функциональности, и может кто-то порекомендовать подходящие плагины?

Вам не обязательно нужен готовый плагин для этого, или вы можете создать собственный легкий плагин. Вот как я бы подошел к решению проблемы:

  1. Вам нужно, чтобы приложение запоминало уже выбранный фильтр и передавало все значения фильтра каждый раз, когда вы изменяете свой выбор.
  2. Поэтому вашим самым безопасным вариантом будет создание формы с таким количеством <select> полей, сколько у вас таксономий для фильтрации.
  3. Вы заполните эти поля всеми вашими терминами и затем скроете форму. Значения <option> value будут равны slug’ам термина.
  4. Затем вы сгенерируете стандартное облако термов, используя wp_tag_cloud и свяжете его с скрытыми фильтрами <select> с помощью JavaScript.
  5. Каждый раз, когда вы нажимаете на ссылку в облаке, вы изменяете соответствующий фильтр поля <select> и отправляете форму.
  6. Когда форма отправляется, вы получите настройки фильтра из $_GET и выполните запрос и фильтрацию записей, используя new WP_Query.
  7. Вы отобразите запрашиваемые записи. Простой вопрос!

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

<?php
    // Перечислите все таксономии, которые хотите связать
    $taxonomies = array( 'genre', 'writer' );

    // Создает вспомогательные $genres_list, $writers_list и т.д., которые содержат все их термины
    foreach( $taxonomies as $taxonomy )
        ${$taxonomy . 's_list'} = get_terms( $taxonomy, array() );
?>

<!-- Создайте скрытые <select>, которые будут фильтровать наши данные -->
<form method="GET" id="filter-manager">

    <?php foreach( $taxonomies as $taxonomy ): ?>
        <select id="<?= $taxonomy ?>_filter" name="<?= $taxonomy ?>_filter">
            <option value="">(нет)</option>
        <?php foreach( ${$taxonomy . 's_list'} as $taxonomy_object ): ?>
            <?php $selected = ( isset( $_GET[$taxonomy . '_filter'] ) && $_GET[$taxonomy . '_filter'] === $taxonomy_object->slug ) ? ' selected="selected"' : ''; ?>
            <option value="<?= $taxonomy_object->slug ?>"<?= $selected ?>><?= $taxonomy_object->name ?></option>
        <?php endforeach; ?>
        </select>
    <?php endforeach; ?>

</form>

<?php
    // Отобразите облака тегов для всех таксономий
    foreach( $taxonomies as $taxonomy ) {
        $cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false ) );

        // Добавьте данные таксономии к каждой ссылке
        $cloud = preg_replace( '~>([^<]+)<~U', ' data-taxonomy="' . $taxonomy . '">$1<', $cloud );

        echo $cloud;
    }
?>

<script>

    (function($) {
        // Скрыть менеджер фильтров
        $form = $('#filter-manager');
        $form.find('select').on('change', function() {
            $form.submit();
        }).hide();

        // Передать клики по облаку в соответствующий менеджер фильтров
        $('a[class*="tag-link"]').on('click', function(e) {
            e.preventDefault();
            var taxonomy = $(this).data('taxonomy');
            var $link = $(this);
            $form.find('select#' + taxonomy + '_filter option').filter( function() {
                return ( $(this).text() == $link.text() );
            }).prop('selected', true);
            $form.find('select#' + taxonomy + '_filter option').trigger('change');
        });
    })(jQuery);

</script>

<?php

    // Создайте аргументы WP_Query, измените по вашему усмотрению
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1
    );

    // Создает WP_Query, который фильтрует только те записи, которые нам нужны
    foreach( $taxonomies as $taxonomy )
        if ( isset( $_GET[$taxonomy . '_filter'] ) and (bool) $_GET[$taxonomy . '_filter'] === true )
            $args = array_merge( $args, array( $taxonomy => $_GET[$taxonomy . '_filter'] ) );

    $filtered_posts = new WP_Query( $args );

    // Перечислить отфильтрованные записи
    while( $filtered_posts->have_posts() ): $filtered_posts->the_post();
?>
    <div class="post">
        <?php
            echo '<h2>' . get_the_title() . '</h2>';
            the_content();
        ?>
    </div>
<?php
    endwhile;

.

Ответ или решение

Вопрос создания фильтров для кастомного типа постов с использованием облаков тегов по нескольким таксономиям актуален в разработке на WordPress, и его реализация действительно может значительно улучшить пользовательский интерфейс вашего сайта. Рассмотрим ключевые аспекты данной задачи, используемую архитектуру и пример реализации данного функционала.

1. Цели и задачи проекта

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

2. Ключевые аспекты реализации

Для успешного выполнения задачи необходимо учитывать следующие этапы:

a. Хранение выбранных фильтров

Необходимо сохранить выбранные пользователем значения фильтров. Это можно сделать с помощью обычной HTML-формы, где каждое значение будет представлено в виде элемента <select>. При каждом изменении пользователем выбора, фильтры должны динамически обновляться и отправляться на сервер.

b. Создание скрытых элементов форм

Чтобы сохранять выбранные значения и передавать их на сервер, создаем скрытые поля формы с тегами <select>. Каждый из них будет связан с определенной таксономией, отображая доступные термины.

c. Генерация облаков тегов

Используя функцию wp_tag_cloud(), можно создать облака тегов для обеих таксономий. Каждое облако тегов отправляет свою информацию о терминах в соответствующие скрытые поля формы.

d. AJAX-запросы (по желанию)

Для улучшения пользовательского интерфейса можно использовать AJAX, чтобы обновлять содержимое страницы без перезагрузки. Но это требует дополнительной реализации.

3. Пример кода

Ниже приведен пример реализации описанного функционала:

<?php
// Перечень таксономий для фильтрации
$taxonomies = array('genre', 'writer');

// Получение терминов для каждой таксономии
foreach ($taxonomies as $taxonomy) {
    ${$taxonomy . 's_list'} = get_terms($taxonomy, array());
}

// Создание скрытых select для фильтров
echo '<form method="GET" id="filter-manager">';
foreach ($taxonomies as $taxonomy) {
    echo '<select id="' . $taxonomy . '_filter" name="' . $taxonomy . '_filter">';
    echo '<option value="">(none)</option>';
    foreach (${$taxonomy . 's_list'} as $term) {
        $selected = (isset($_GET[$taxonomy . '_filter']) && $_GET[$taxonomy . '_filter'] === $term->slug) ? ' selected="selected"' : '';
        echo '<option value="' . $term->slug . '"' . $selected . '>' . $term->name . '</option>';
    }
    echo '</select>';
}
echo '</form>';

// Отображение облаков тегов
foreach ($taxonomies as $taxonomy) {
    $cloud = wp_tag_cloud(array('taxonomy' => $taxonomy, 'echo' => false));
    // Добавление данных о таксономиях к ссылкам
    $cloud = preg_replace('~>([^<]+)<~U', ' data-taxonomy="' . $taxonomy . '">$1<', $cloud);
    echo $cloud;
}
?>
<script>
(function($) {
    // Скрытие фильтров
    var $form = $('#filter-manager');
    $form.find('select').on('change', function() {
        $form.submit();
    }).hide();
    // Передача кликов по облакам в соответствующие фильтры
    $('a[class*="tag-link"]').on('click', function(e) {
        e.preventDefault();
        var taxonomy = $(this).data('taxonomy');
        var $link = $(this);
        $form.find('select#' + taxonomy + '_filter option').filter(function() {
            return ($(this).text() == $link.text());
        }).prop('selected', true);
        $form.find('select#' + taxonomy + '_filter option').trigger('change');
    });
})(jQuery);
</script>

<?php
// Запрос постов
$args = array(
    'post_type' => 'post',
    'posts_per_page' => -1,
);
foreach ($taxonomies as $taxonomy) {
    if (isset($_GET[$taxonomy . '_filter']) && $_GET[$taxonomy . '_filter']) {
        $args[$taxonomy] = $_GET[$taxonomy . '_filter'];
    }
}
$filtered_posts = new WP_Query($args);

// Вывод постов
while ($filtered_posts->have_posts()) : $filtered_posts->the_post();
    echo '<div class="post">';
    echo '<h2>' . get_the_title() . '</h2>';
    the_content();
    echo '</div>';
endwhile;
?>

4. Заключение

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

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

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

Капча загружается...