🔧 add_action( 'pre_get_posts', ... )
📍 Когда используется:
Этот хук вызывается до того, как WordPress выполнит SQL-запрос в базу данных.
📌 Что ты можешь сделать:
Ты можешь изменить параметры запроса, например:
- Тип постов (
post_type) - Количество (
posts_per_page) - Сортировку (
orderby,order) - Фильтрацию по таксономиям (
tax_query) - Исключить или включить посты и многое другое
🧠 В твоём коде:
function modify_query_order_for_providers( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
$request_path = trim( $_SERVER['REQUEST_URI'], '/' );
if ( $request_path === 'providers' || strpos( $request_path, 'providers/' ) === 0 ) {
$query->set( 'post_type', 'projects' );
$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' );
}
}
}
add_action( 'pre_get_posts', 'modify_query_order_for_providers' );
🧹 add_filter( 'the_posts', ... )
📍 Когда используется:
Этот хук вызывается после того, как WordPress уже выполнил SQL-запрос и получил массив постов.
📌 Что ты можешь сделать:
Ты не можешь изменить параметры запроса, но можешь:
- Изменить порядок записей (кастомная сортировка)
- Убрать/добавить посты вручную
- Группировать их или вставить искусственные посты
- Например, отфильтровать по кастомным меткам, отношениям, сложной логике и т. д.
🧠 В твоём коде:
function custom_modify_and_sort_providers( $posts, $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
$request_path = trim( $_SERVER['REQUEST_URI'], '/' );
if ( $request_path === 'providers' || strpos( $request_path, 'providers/' ) === 0 ) {
$ncris = [];
$non_ncris = [];
foreach ( $posts as $post ) {
if ( has_term( 'yes', 'ncris-provider', $post->ID ) ) {
$ncris[] = $post;
} else {
$non_ncris[] = $post;
}
}
usort( $ncris, fn($a, $b) => strcmp($a->post_title, $b->post_title) );
usort( $non_ncris, fn($a, $b) => strcmp($a->post_title, $b->post_title) );
$posts = array_merge( $ncris, $non_ncris );
}
}
return $posts;
}
add_filter( 'the_posts', 'custom_modify_and_sort_providers', 10, 2 );
Когда использовать что?
| Цель | Использовать pre_get_posts | Использовать the_posts |
|---|---|---|
| Изменить SQL-запрос (тип, сортировка, фильтры) | ✅ Да | ❌ Нет |
| Влиять на то, какие посты будут запрошены из базы | ✅ Да | ❌ Нет |
| Переупорядочить полученные посты вручную | ❌ Нет | ✅ Да |
| Разделить посты по условию (например, NCRIS yes / no) | 🚫 Трудно (в SQL) | ✅ Легко |
| Добавить искусственные посты или удалить некоторые | ❌ Нет | ✅ Да |
Вывод для твоей задачи:
Тебе стоит использовать оба хука вместе:
pre_get_posts— чтобы задать нужный post_type (projects) и отсортировать по title ASC.the_posts— чтобы разделить полученные посты на группы по наличию NCRIS и реорганизовать порядок вручную.
Если хочешь оставить всё в одной функции, как ты сделал — то можно просто использовать the_posts и переупорядочивать только, не трогая SQL.
function custom_modify_and_sort_providers( $posts, $query ) {
// Применяем функционал только для основного запроса на фронтенде.
if ( ! is_admin() && $query->is_main_query() ) {
// Определяем текущий URL (без ведущих и завершающих слешей).
$request_path = trim( $_SERVER['REQUEST_URI'], '/' );
// Если мы находимся на странице провайдеров
if ( $request_path === 'providers' || strpos( $request_path, 'providers/' ) === 0 ) {
$ncris_funded = array();
$non_ncris_funded = array();
// Разбиваем записи на две группы.
foreach ( $posts as $post ) {
// Функция has_term проверяет, связан ли пост с термином 'yes' в таксономии 'ncris-provider'.
if ( has_term( 'yes', 'ncris-provider', $post->ID ) ) {
$ncris_funded[] = $post;
} else {
$non_ncris_funded[] = $post;
}
}
// Сортируем каждую группу по заголовку.
usort( $ncris_funded, function( $a, $b ) {
return strcmp( $a->post_title, $b->post_title );
} );
usort( $non_ncris_funded, function( $a, $b ) {
return strcmp( $a->post_title, $b->post_title );
} );
// Объединяем так, чтобы в начале шли NCRIS-funded провайдеры.
$posts = array_merge( $ncris_funded, $non_ncris_funded );
}
}
return $posts;
}
add_filter( 'the_posts', 'custom_modify_and_sort_providers', 10, 2 );
