Вопрос или проблема
Фильтрация постов в подкатегориях не работает
/category/child-category-1/filter_xxx-yyy/ – РАБОТАЕТ
/category/child-category-1/child-category-2/filter_xxx-yyy/ – НЕ работает
/category/child-category-1/child-category-2/child-category-3/filter_xxx-yyy/ – НЕ работает
add_action('pre_get_posts', array($this, 'filter_posts_by_custom_fields'));
add_action('init', array($this, 'register_rewrite_rules'));
public function register_rewrite_rules() {
add_rewrite_rule('^category/([^/]+)/(.+)/?$', 'index.php?category_name=$matches[1]&custom_filter=$matches[2]', 'top');
add_rewrite_tag('%custom_filter%', '([^&]+)');
}
public function filter_posts_by_custom_fields($query) {
if (!$query->is_main_query() || !is_category() || !$query->get('custom_filter')) return;
$custom_filter = $query->get('custom_filter');
$filters = explode('-and-', $custom_filter);
$meta_query = ['relation' => 'AND'];
foreach ($filters as $filter) {
if (strpos($filter, 'filter_') === 0) {
list($key, $value) = explode('-', $filter, 2);
$values = explode('-plus-', $value);
$meta_query[] = [
'key' => $key,
'value' => count($values) > 1 ? $values : $value,
'compare' => count($values) > 1 ? 'IN' : '='
];
}
}
$query->set('meta_query', $meta_query);
}
Как я могу сделать фильтр работающим на всех уровнях категорий?
Извините за мой английский.
Ответ или решение
Для решения проблемы с фильтрацией постов в дочерних категориях в WordPress, необходимо разобраться в коде, который отвечает за обработку пользовательских фильтров и перезапись правил URL. Правильная реализация этих компонентов обеспечит корректную работу фильтрации на всех уровнях иерархии категорий.
Анализ текущего кода
В вашем коде уже предусмотрены необходимые действия для фильтрации. Действие pre_get_posts
отвечает за модификацию основного запроса, а init
занимается регистрацией правил перезаписи.
-
Регистрация правил перезаписи:
add_rewrite_rule('^category/([^/]+)/(.+)/?$', 'index.php?category_name=$matches[1]&custom_filter=$matches[2]', 'top'); add_rewrite_tag('%custom_filter%', '([^&]+)');
Здесь вы регистрируете правило, которое обрабатывает URL вида
/category/дочерняя-категория/filter_xxx-yyy/
. Однако, для обеспечения работы фильтров в более глубоких вложенных категориях необходимо отказаться от жёсткой привязки к одному уровню. -
Фильтрация постов по пользовательским полям:
public function filter_posts_by_custom_fields($query) { if (!$query->is_main_query() || !is_category() || !$query->get('custom_filter')) return; $custom_filter = $query->get('custom_filter'); // Логика обработки фильтров }
В этом методе выполняется проверка текущего запроса и наличие пользовательского фильтра. Однако, из-за проверки на
is_category()
, фильтры могут не применяться для более глубоких уровней категории.
Рекомендации по исправлению
Чтобы обеспечить работу фильтров для всех уровней вложенности категорий, необходимо внести изменения в оба метода: как в регистрацию правил перезаписи, так и в обработку запросов.
-
Обновление правил перезаписи:
Нужно обновить правило, чтобы оно корректно обрабатывало категории любой вложенности. Используйте следующую конструкцию для обработки произвольного количества уровней категорий:add_rewrite_rule('^category/(.+?)/(.+)/?$', 'index.php?category_name=$matches[1]&custom_filter=$matches[2]', 'top');
В данной записи используется регулярное выражение
(.+?)
, которое позволяет захватывать категорию, включая вложенные категории. -
Изменения в фильтрации постов:
Измените условие проверки, чтобы оно учитывало и вложенные категории:public function filter_posts_by_custom_fields($query) { if (!$query->is_main_query() || !is_category() || !isset($query->query_vars['custom_filter'])) return; $custom_filter = $query->get('custom_filter'); // Логика обработки фильтров }
В этом фрагменте важно использовать
isset()
, чтобы избежать потенциальных ошибок, если ключаcustom_filter
нет в массивеquery_vars
. -
Тестирование и очистка кэша:
После внесения изменений не забудьте протестировать все возможные URL и выполнить обновление постоянных ссылок в админ-панели WordPress (Настройки -> Постоянные ссылки). Это потребуется для сброса кэша правил перезаписи.
Заключение
Внедрение предложенных изменений связанных с регистрацией правил перезаписи и обработкой запросов позволит эффективно применять фильтры на всех уровнях категорий в WordPress. Убедитесь, что все изменения полностью протестированы, чтобы гарантировать их корректную работу и избежать ошибок в будущем. Это значительно улучшит функциональность вашего сайта и опыт работы пользователей.