Изменение страниц таксономий для исключения элементов из дочерних таксономий
Я нашел этот вопрос:
Можно ли использовать $query->set('tax_query' в фильтре pre_get_posts?
который, кажется, указывает, что да, можно изменять запрос таксономии на архивах таксономий через pre_get_posts(). Поэтому я придумал:
add_action('pre_get_posts', 'kia_no_child_terms' );
function kia_no_child_terms( $wp_query ) {
if( is_tax() ) {
$wp_query->tax_query->queries[0]['include_children'] = 0;
}
}
а также
add_action('pre_get_posts', 'kia_no_child_terms' );
function kia_no_child_terms( $wp_query ) {
if( is_tax() ) {
$tax_query = $wp_query->get( 'tax_query' );
$tax_query->queries[0]['include_children'] = 0;
$wp_query->set( 'tax_query', $tax_query );
}
}
чтобы попытаться установить параметр include_children в false... и практически все комбинации из этого, которые я мог придумать. Однако до сих пор архив таксономии продолжает показывать элементы из дочерних терминов.
И следующий тест просто ДОБАВЛЯЕТ дополнительные tax_query вместо их перезаписи... что меня сбивает с толку.
function dummy_test( $wp_query){
$tax_query = array(
'relation' => 'OR',
array(
'taxonomy' => 'tax1',
'terms' => array( 'term1', 'term2' ),
'field' => 'slug',
),
array(
'taxonomy' => 'tax2',
'terms' => array( 'term-a', 'term-b' ),
'field' => 'slug',
),
);
$wp_query->set( 'tax_query', $tax_query );
);
add_action('pre_get_posts','dummy_test');
Разве SET не должен перезаписывать текущее значение?

Я знаю, что это старый вопрос, но он может быть немного запутанным и, надеюсь, поможет кому-то. Причина, по которой `$query->set` не работает, заключается в том, что запрос уже был обработан, и теперь нам также нужно обновить объект tax_query. Вот как я это сделал:
function my_tax_query( $query ) {
$package_id = 12345;
$tax_query = array(
'taxonomy' => 'package_id',
'terms' => array( $package_id ),
'field' => 'slug',
'operator' => 'IN',
);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
}
add_action( 'pre_get_posts', 'my_tax_query' );

Отлично!! Я проверил это и смог адаптировать ваш код для работы со всеми таксономиями, что и было в исходном вопросе. +1 (я бы поставил больше голосов, если бы мог)

Я был удивлён и обрадован, увидев, что этот метод также работает для запросов по дате.

Начиная с WordPress 3.7 был добавлен новый экшен parse_tax_query
именно для этой цели.
function kia_no_child_terms($wp_query) {
$wp_query->tax_query->queries[0]['include_children'] = 0;
}
add_action('parse_tax_query', 'kia_no_child_terms');
Этот хук изменяет значения как query_vars, так и tax_query. Использование метода pre_get_posts
приводило к дублированию таксономических запросов, по крайней мере в моем случае.
До версии 3.7 необходимо использовать экшен pre_get_posts
, как подробно описано в других ответах.

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

@Manu - вы абсолютно правы. Приведенный пример очень упрощен и показывает только соответствующие переменные. В реальном сценарии вы бы проверяли $wp_query
, использовали теги шаблонов, или и то и другое, или какую-то другую логику, чтобы определить, следует ли вообще изменять запрос.

Я не смог заставить это работать ни с какими комбинациями pre_get_posts
или parse_query
. Я могу сделать это относительно легко, сбросив объект запроса после его создания. Мне это не нравится, потому что тогда запрос выполняется дважды, но я уже исчерпал все варианты, пытаясь быть "эффективным".
function kia_no_child_taxonomies(){
if(is_tax()){
$args = array(
'tax_query' => array(
array(
'taxonomy' => get_query_var('taxonomy'),
'field' => 'slug',
'terms' => get_query_var('term'),
'include_children' => false
)
)
);
query_posts($args);
}
}
add_action('wp','kia_no_child_taxonomies');
Так что, пока кто-нибудь не предложит лучший ответ, это единственный метод, который я пока нашел.
ОБНОВЛЕНИЕ:
Адаптировав ответ от @Tanner Moushey, мне наконец удалось заставить это работать для исключения всех дочерних терминов из архива таксономии на хуке pre_get_posts
без неэффективного двойного запроса.
function kia_no_child_taxonomies( $query ) {
if( is_tax() ):
$tax_obj = $query->get_queried_object();
$tax_query = array(
'taxonomy' => $tax_obj->taxonomy,
'field' => 'slug',
'terms' => $tax_obj->slug,
'include_children' => false
);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
endif;
}
add_action( 'pre_get_posts', 'kia_no_child_taxonomies' );

Это неправильно. Не следует использовать query_posts, вместо этого используйте pre_get_posts или request.

это бесполезно. почему бы тогда не опубликовать ответ, если ты знаешь, как заставить pre_get_posts работать в данном случае? я явно указал в своем вопросе, что пробовал это, но пришел к выводу, что нельзя модифицировать объект tax_Query через этот фильтр

Извини, должен был быть более полезным. Настоящий tax query формируется (с помощью parse_tax_query) после срабатывания pre_get_posts, и в реальном WP_Tax_Query, который содержит все tax queries, объединенные из переменных запроса (включая переменную запроса tax_query), так что в твоем случае он парсит твою переменную запроса tax_query, а затем добавляет все остальное, что доступно через переменные запроса, такие как category, tag__in и другие. Ты можешь использовать pre_get_posts для удаления существующих переменных запроса перед добавлением своих собственных.

Спасибо за более подробное объяснение. Очевидно, это уже устарело, так что я продолжил с тем решением, которое у меня было. Мне так и не удалось изменить параметр include_children
через хук pre_get_posts
. Ну что ж.

Похоже, я тоже столкнулся с этой проблемой. :-/

Для тех, кто, как и я, столкнулся с этой проблемой, я нашел полезное решение. Я использовал систему приоритетов:
function kia_no_child_taxonomies( $query ) {
if( is_tax() ):
$tax_obj = $query->get_queried_object();
$tax_query = array(
'taxonomy' => $tax_obj->taxonomy,
'field' => 'slug',
'terms' => $tax_obj->slug,
'include_children' => FALSE);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
return $query;
endif;
}
add_action( 'pre_get_posts', 'kia_no_child_taxonomies',0 );
Мой запрос не включался в результаты, и поиск не работал с моими исключениями. Надеюсь, это поможет.

Я наткнулся на следующую ветку обсуждения в WP Core и успешно использую этот код для исключения дочерних элементов для определенной таксономии:
function wpse_43181_parse_tax_query( $query ) {
if ( ! empty( $query->tax_query->queries ) ) {
foreach ( $query->tax_query->queries as &$tax_query ) {
if ( $tax_query['taxonomy'] === 'your_taxonomy' ) {
$tax_query['include_children'] = false;
}
}
}
}
add_action( 'parse_tax_query', 'wpse_43181_parse_tax_query' );
Модифицируйте его по своему усмотрению, чтобы исключать дочерние элементы для всех страниц таксономий.
