Не удается фильтровать категории с помощью изотопа.

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

Я пытаюсь инициализировать Isotope https://isotope.metafizzy.co/ в WordPress, чтобы начать фильтровать посты по их категориям. Думаю, мне не хватает какого-то PHP в секции <a href="#" data-filter=".".$term->slug."">" . $term->name . "</a>, потому что когда я нажимаю на категорию, у меня появляется /# вместо фильтрации категорий. Я действительно пытаюсь достичь этого эффекта фильтрации: https://nmbw.com.au/works-and-projects/

Я новичок в этом, поэтому любая помощь будет действительно полезна.

Вот что у меня есть:

<?php
/**
 * Название шаблона: isotope
 *
 * Шаблон для отображения страницы без боковой панели, даже если виджет боковой панели опубликован.
 *
 * @package understrap
 */

get_header();
$container = get_theme_mod( 'understrap_container_type' );
?>

<ul id="filters">
    <li><a href="#" data-filter="*">Все категории</a></li>
<?php
$terms = get_terms("category"); // получить все категории, но вы можете использовать любую таксономию
$count = count($terms); //Сколько их?
if ( $count > 0 ){  //Если терминов больше 0
foreach ( $terms as $term ) {  //для каждого термина:
echo "<li><a href="#" data-filter=".".$term->slug."">" . $term->name . "</a></li>\n";
//создать элемент списка с текущим слага терминов для сортировки и именем для метки
}
}
?>
</ul>

<?php $the_query = new WP_Query( 'posts_per_page=9' ); //Проверьте документацию WP_Query, чтобы увидеть, как можно ограничить отображаемые посты ?>
<?php if ( $the_query->have_posts() ) : ?>
    <div id="isotope-list">
    <?php while ( $the_query->have_posts() ) : $the_query->the_post();
$termsArray = get_the_terms( $post->ID, "category" );  //Получить термины для этого конкретного элемента
$termsString = ""; //инициализировать строку, которая будет содержать термины
foreach ( $termsArray as $term ) { // для каждого термина
$termsString .= $term->slug.' '; //создать строку, которая имеет все слаги
}
?>
<div class="<?php echo $termsString; ?> item">
<h3><?php the_title(); ?></h3>
        <?php if ( has_post_thumbnail() ) {
                      the_post_thumbnail();
                } ?>
</div> <!-- конец элемента -->
    <?php endwhile;  ?>
    </div> <!-- конец списка изотопов -->
<?php endif; ?>
<?php get_footer(); ?>

Вот что у меня есть в моем файле functions.php

function add_isotope() {
wp_register_script( 'isotope', get_template_directory_uri().'/js/libs/isotope.pkgd.min.js', array('jquery'),  true );
wp_register_script( 'isotope-init', get_template_directory_uri().'/js/isotope.js', array('jquery', 'isotope'),  true );
wp_register_script( 'isotope-custom', get_template_directory_uri().'/js/isotope-custom.js', array('jquery', 'isotope'),  true );
wp_register_style( 'isotope-css', get_stylesheet_directory_uri() . '/css/isotope.css' );

wp_enqueue_script('isotope-init');
wp_enqueue_style('isotope-css');
}

add_action( 'wp_enqueue_scripts', 'add_isotope' );  

Это в моем файле isotope-custom.js

jQuery(function ($) {

var $container = $('#isotope-list'); //ID для списка со всеми 
блог-постами
$container.isotope({ //Опции Isotope, 'item' соответствует классу в 
PHP
itemSelector : '.item', 
layoutMode : 'masonry'
});

//Добавить класс selected к элементу, на который кликнули, и удалить его у 
остальных
var $optionSets = $('#filters'),
$optionLinks = $optionSets.find('a');

$optionLinks.click(function(){
var $this = $(this);
// не продолжать, если уже выбрано
if ( $this.hasClass('selected') ) {
return false;
}
var $optionSet = $this.parents('#filters');
$optionSets.find('.selected').removeClass('selected');
$this.addClass('selected');

//Когда элемент нажат, отсортировать элементы.
var selector = $(this).attr('data-filter');
$container.isotope({ filter: selector });

return false;
});

});

Это в файле isotope.js
`jQuery(function ($) {

 //установите контейнер, в котором будет находиться Isotope, в переменную

 var container = document.querySelector('#isotope-list');

 //создайте пустую переменную isotope

 var Isotope;

 // инициализируйте Isotope после загрузки всех изображений
 var $container = $('#isotope-list').imagesLoaded( function() {
 $container.isotope({
 // опции
 });
 });

 var $container = $('#isotope-list'); //ID для списка со всеми 
 блог-постами
 $container.isotope({ //Опции Isotope, 'item' соответствует классу в 
 PHP
 itemSelector : '.item',
 layoutMode : 'masonry',
 isOriginLeft: false
 });
 var container = document.querySelector('#isotope-list');
 // инициализация
 var iso = new Isotope( container, {
 // опции
 itemSelector: '.item',

 });

 //Добавить класс selected к элементу, на который кликнули, и удалить его у 
остальных
 var $optionSets = $('#filters'),
 $optionLinks = $optionSets.find('a');

  $optionLinks.click(function(){
  var $this = $(this);
  // не продолжать, если уже выбрано
  if ( $this.hasClass('selected') ) {
  return false;
  }
  var $optionSet = $this.parents('#filters');
  $optionSets.find('.selected').removeClass('selected');
  $this.addClass('selected');

  //Когда элемент нажат, отсортировать элементы.
  var selector = $(this).attr('data-filter');
  $container.isotope({ filter: selector });

  return false;
  });

  });

  jQuery( function($) {

  $('.isotope').isotope({
  itemSelector: '.item',
  masonry: {
  columnWidth: 100
  }
  });

  });`

Попробуйте предотвратить стандартное поведение события клика, используя jQuery с самого начала:

jQuery(function ($) {

var $container = $('#isotope-list'); //ID для списка со всеми 
блог-постами
var $isotope = $container.isotope({ //Опции Isotope, 'item' соответствует классу в 
PHP
itemSelector : '.item', 
layoutMode : 'masonry'
});

//Добавить класс selected к элементу, на который кликнули, и удалить его у 
остальных
var $optionSets = $('#filters'),
$optionLinks = $optionSets.find('a');

$optionLinks.click(function(e){
e.preventDefault();
var $this = $(this);
// не продолжать, если уже выбрано
if ( $this.hasClass('selected') ) {
return false;
}
var $optionSet = $this.parents('#filters');
$optionSets.find('.selected').removeClass('selected');
$this.addClass('selected');

//Когда элемент нажат, отсортировать элементы.
var selector = $(this).attr('data-filter');
$isotope.isotope({ filter: selector });

return false;
});

});

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

Проблема с фильтрацией категорий с использованием Isotope в WordPress

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

1. Исправление ошибок в HTML и PHP

Ваша строка кода для создания ссылки на фильтр категорий содержит некорректное формирование HTML:

echo "<li><a href=\"#\" data-filter=\".".$term->slug."\">" . $term->name . "</a></li>\n";

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

echo "<li><a href=\"#\" data-filter=\"." . esc_attr($term->slug) . "\">" . esc_html($term->name) . "</a></li>\n";

Использование esc_attr() и esc_html() — это хорошая практика для обеспечения безопасности и корректного отображения данных.

2. Корректная инициализация скриптов

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

Ты должнен использовать правильный хук:

wp_enqueue_script('isotope-init', get_template_directory_uri() . '/js/isotope.js', array('jquery', 'isotope'), null, true);

3. Обработка кликов и предотвращение стандартного поведения

Ваши обработчики кликов должны предотвращать стандартное поведение ссылки (то есть переход по ссылке). Для этого вы можете использовать метод e.preventDefault().

Вот пример того, как это должно выглядеть:

$optionLinks.click(function(e) {
    e.preventDefault(); // Остановите стандартное поведение

    var $this = $(this);

    // Проверка на уже выделенную кнопку
    if ($this.hasClass('selected')) {
        return false;
    }

    var $optionSet = $this.parents('#filters');
    $optionSets.find('.selected').removeClass('selected');
    $this.addClass('selected');

    // Применяем фильтрацию
    var selector = $this.attr('data-filter');
    $container.isotope({ filter: selector });

    return false; // Возвращаем false для предотвращения дальнейшей обработки
});

4. Инициализация Isotope после загрузки изображений

Убедитесь, что вы вызываете Isotope после полной загрузки изображений. Это важно, так как Isotope рассчитывает размеры элементов, и если изображения не загружены, он может работать некорректно.

Используйте библиотеку ImagesLoaded в сочетании с Isotope:

$container.imagesLoaded(function() {
    $container.isotope({
        itemSelector: '.item',
        layoutMode: 'masonry'
    });
});

5. Пример работы с кодом

Вот полная версия вашего JavaScript для реализации фильтрации с использованием Isotope и корректным предотвращением стандартного поведения:

jQuery(function ($) {
    var $container = $('#isotope-list');

    // Initialize Isotope
    $container.imagesLoaded(function() {
        $container.isotope({
            itemSelector: '.item',
            layoutMode: 'masonry'
        });
    });

    // Filter handling
    var $optionSets = $('#filters'),
        $optionLinks = $optionSets.find('a');

    $optionLinks.click(function(e) {
        e.preventDefault();

        var $this = $(this);

        if ($this.hasClass('selected')) {
            return false;
        }

        var $optionSet = $this.parents('#filters');
        $optionSets.find('.selected').removeClass('selected');
        $this.addClass('selected');

        var selector = $this.attr('data-filter');
        $container.isotope({ filter: selector });

        return false;
    });
});

Заключение

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

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

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