- Вопрос или проблема
- Ответ или решение
- Проблема с фильтрацией категорий с использованием Isotope в WordPress
- 1. Исправление ошибок в HTML и PHP
- 2. Корректная инициализация скриптов
- 3. Обработка кликов и предотвращение стандартного поведения
- 4. Инициализация Isotope после загрузки изображений
- 5. Пример работы с кодом
- Заключение
Вопрос или проблема
Я пытаюсь инициализировать 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 для безопасности, а также проверьте правильность инициализации ваших скриптов и обработчиков событий. Удачи в работе над вашим проектом!