Вопрос или проблема
Я использую плагин FacetWP для создания страницы списка постов. Мне нужно упорядочить посты на основе типа таксономии, связанной с типом поста. Затем необходимо переупорядочить посты по их заголовкам после применения порядка таксономии. Как я могу этого добиться?
Ниже приведен пример аргумента запроса для настройки FacetWP,
<?php
return [
"post_type" => [
"partners"
],
"post_status" => [
"publish"
],
"orderby" => [
"title" => "ASC"
],
"posts_per_page" => 9
];
Этот ответ для порядка терминов таксономии плагина “Category Order and Taxonomy Terms Order”.
/**
* Чтобы добавить дополнительный параметр для запроса фасета
*/
add_filter('facetwp_query_args', function ($query_args, $class) {
if ($class->ajax_params['template'] == 'partner_posts') {
$tax_terms = get_terms(array(
'taxonomy' => 'your-taxonomy-name',
'fields' => 'ids',
'hide_empty' => true,
));
$query_args['tax_query'] = array(
array(
'taxonomy' => 'your-taxonomy-name',
'terms' => $tax_terms
)
);
$query_args['uid'] = 'your-uid'; //добавьте уникальный uid для отдельной идентификации запроса
}
return $query_args;
}, 10, 2);
// добавьте мой фильтр для изменения порядка запроса, выполненного WP_QUERY:
add_filter('posts_orderby', function ($order_by_statement, WP_Query $query) {
global $wpdb;
if (
!isset($query->query_vars['uid'])
|| (isset($query->query_vars['uid']) && $query->query_vars['uid'] !== 'your-uid')
) {
return $order_by_statement;
}
$table_prefix = $wpdb->prefix;
return " {$table_prefix}terms.term_order ASC"
. (!empty($order_by_statement) ? ',' : '')
. $order_by_statement; //сохраняет текущий порядок, но также добавляет term_order в начале
}, 10, 2);
add_filter('posts_join', function ($join_statements, WP_Query $query) {
global $wpdb;
if (
!isset($query->query_vars['uid'])
|| (isset($query->query_vars['uid']) && $query->query_vars['uid'] !== 'your-uid')
) {
return $join_statements;
}
$table_prefix = $wpdb->prefix;
$join_statements .= ' ' . <<<QUERY
LEFT JOIN {$table_prefix}term_taxonomy
ON ({$table_prefix}term_taxonomy.term_taxonomy_id = {$table_prefix}term_relationships.term_taxonomy_id)
LEFT JOIN {$table_prefix}terms ON ({$table_prefix}terms.term_id = {$table_prefix}term_taxonomy.term_id)
QUERY;
return $join_statements;
}, 10, 2);
Ответ или решение
Для реализации сортировки записей по таксономии при использовании плагина FacetWP и последующей сортировки по заголовку, вы можете использовать следующий подход, который состоит из нескольких ключевых шагов.
Теория: Понимание того, как работает WordPress Query и механизм плагинов для фильтрации и сортировки данных, важно для успешной настройки. Плагин FacetWP позволяет динамически фильтровать данные на основе таксономий и других параметров. В то же время, необходимость использовать таксономию для сортировки требует применения нестандартного подхода, так как WordPress по умолчанию сортирует записи другими параметрами, такими как дата или заголовок.
Пример: Предположим, у вас есть тип записи "partners", и вам необходимо сначала отсортировать записи на основе пользовательского порядка таксономии "your-taxonomy-name", заданного с использованием плагина "Category Order and Taxonomy Terms Order", а затем отсортировать записи по заголовкам. Плагин "Category Order and Taxonomy Terms Order" добавляет возможность настраивать порядок терминов в таксономии. Вы можете использовать это для сортировки записей по порядку терминов.
Реализация:
-
Фильтрация FacetWP: Используйте фильтр
facetwp_query_args
, чтобы добавить дополнительные параметры к запросу. Этот фильтр позволяет модифицировать аргументы запроса, которые FacetWP использует для извлечения данных. -
Запрос по таксономии: Получите идентификаторы терминов таксономии, используя функцию
get_terms()
, и создайте массив дляtax_query
вWP_Query
. Убедитесь, что вы добавляете уникальный идентификаторuid
, чтобы позже корректно идентифицировать и модифицировать запрос. -
Обработка порядка сортировки записей: С использованием фильтра
posts_orderby
, добавьте пользовательский порядок сортировки с использованием SQL JOIN для получения и использованияterm_order
. Учтите, что вы должны убедиться, что текущий запрос имеет установленный уникальный идентификаторuid
, что позволяет менять порядок сортировки только для нужных запросов. -
Соединение таблиц в запросе: Используйте фильтр
posts_join
, чтобы объединить необходимые таблицы базы данных для доступа к информации о терминах, как это показано в приведенном выше примере кода.
Пример кода:
add_filter('facetwp_query_args', function ($query_args, $class) {
if ($class->ajax_params['template'] == 'partner_posts') {
$tax_terms = get_terms(array(
'taxonomy' => 'your-taxonomy-name',
'fields' => 'ids',
'hide_empty' => true,
));
$query_args['tax_query'] = [
[
'taxonomy' => 'your-taxonomy-name',
'terms' => $tax_terms
]
];
$query_args['uid'] = 'your-uid'; // Уникальный UID для отдельного идентифицирования запроса
}
return $query_args;
}, 10, 2);
add_filter('posts_orderby', function ($order_by_statement, WP_Query $query) {
global $wpdb;
if (!isset($query->query_vars['uid']) || $query->query_vars['uid'] !== 'your-uid') {
return $order_by_statement;
}
$table_prefix = $wpdb->prefix;
return " {$table_prefix}terms.term_order ASC" . (!empty($order_by_statement) ? ',' : '') . $order_by_statement;
}, 10, 2);
add_filter('posts_join', function ($join_statements, WP_Query $query) {
global $wpdb;
if (!isset($query->query_vars['uid']) || $query->query_vars['uid'] !== 'your-uid') {
return $join_statements;
}
$table_prefix = $wpdb->prefix;
$join_statements .= <<<JOIN
LEFT JOIN {$table_prefix}term_taxonomy
ON ({$table_prefix}term_taxonomy.term_taxonomy_id = {$table_prefix}term_relationships.term_taxonomy_id)
LEFT JOIN {$table_prefix}terms ON ({$table_prefix}terms.term_id = {$table_prefix}term_taxonomy.term_id)
JOIN;
return $join_statements;
}, 10, 2);
Эта реализация гарантирует, что посты сортируются соответствующим образом сначала по пользовательскому порядку терминов, затем по заголовкам. Обязательно замените your-taxonomy-name
и другие значимы идентификаторы на ваши собственные, соответствующие вашим данным. Убедитесь, что ваш код плотно интегрирован с остальным проектом, чтобы избежать неблагоприятных эффектов или конфликта с другими плагинами или темами.