Понимание внутренних органов
Порядок «сортировки» смежных (следующий / предыдущий) постов на самом деле не является порядком «сортировки». Это отдельный запрос для каждого запроса / страницы, но он сортирует запрос по post_date
- или родительскому посту, если у вас есть иерархическая публикация в качестве отображаемого в данный момент объекта.
Когда вы посмотрите на внутренности next_post_link()
, то увидите, что это в основном оболочка API adjacent_post_link()
. Последняя функция вызывает get_adjacent_post()
внутренне с $previous
аргументом / флагом, установленным для получения bool(true|false)
ссылки на следующую или предыдущую запись.
Что фильтровать?
Углубившись в него, вы увидите, что get_adjacent_post()
ссылка «Источник» имеет несколько хороших фильтров для своего вывода (он же результат запроса): (Имя фильтра / Аргументы)
"get_{$adjacent}_post_join"
$join
// Only if `$in_same_cat`
// or: ! empty( $excluded_categories`
// and then:
// " INNER JOIN $wpdb->term_relationships AS tr
// ON p.ID = tr.object_id
// INNER JOIN $wpdb->term_taxonomy tt
// ON tr.term_taxonomy_id = tt.term_taxonomy_id";
// and if $in_same_cat then it APPENDS:
// " AND tt.taxonomy = 'category'
// AND tt.term_id IN (" . implode(',', $cat_array) . ")";
$in_same_cat
$excluded_categories
"get_{$adjacent}_post_where"
$wpdb->prepare(
// $op = $previous ? '<' : '>'; | $current_post_date
"WHERE p.post_date $op %s "
// $post->post_type
."AND p.post_type = %s "
// $posts_in_ex_cats_sql = " AND tt.taxonomy = 'category'
// AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')';
// OR empty string if $in_same_cat || ! empty( $excluded_categories
."AND p.post_status = 'publish' $posts_in_ex_cats_sql "
",
$current_post_date,
$post->post_type
)
$in_same_cat
$excluded_categories
"get_{$adjacent}_post_sort"
"ORDER BY p.post_date $order LIMIT 1"`
Таким образом, вы можете многое сделать с этим. Это начинается с фильтрации WHERE
предложения, а также JOIN
таблицы ed и ORDER BY
оператора.
Результат кэшируется в памяти для текущего запроса, поэтому он не добавляет дополнительных запросов, если вы вызываете эту функцию несколько раз на одной странице.
Автоматическое построение запросов
Как отметил @StephenHarris в комментариях, есть основная функция, которая может пригодиться при построении SQL-запроса: get_meta_sql()
- Примеры в Кодексе . По сути, эта функция просто используется для построения оператора meta SQL, который используется WP_Query
, но вы можете использовать его и в этом случае (или в других). Аргумент, который вы добавляете в него, является массивом, точно таким же, который добавляется к WP_Query
.
$meta_sql = get_meta_sql(
$meta_query,
'post',
$wpdb->posts,
'ID'
);
Возвращаемое значение представляет собой массив:
$sql => (array) 'join' => array(),
(array) 'where' => array()
Так что вы можете использовать $sql['join']
и $sql['where']
в вашем обратном вызове.
Зависимости, которые нужно иметь в виду
В вашем случае проще всего было бы перехватить его в небольшом (mu) плагине или в файле themes.php вашего файла и изменить его в зависимости от $adjacent = $previous ? 'previous' : 'next';
переменной и $order = $previous ? 'DESC' : 'ASC';
переменной:
Фактические имена фильтров
Итак, имена фильтров:
get_previous_post_join
, get_next_post_join
get_previous_post_where
, get_next_post_where
get_previous_post_sort
, get_next_post_sort
Завёрнутый как плагин
... и обратный вызов фильтра будет (например) примерно таким:
<?php
/** Plugin Name: (#73190) Alter adjacent post link sort order */
function wpse73190_adjacent_post_sort( $orderby )
{
return "ORDER BY p.menu_order DESC LIMIT 1";
}
add_filter( 'get_previous_post_sort', 'wpse73190_adjacent_post_sort' );
add_filter( 'get_next_post_sort', 'wpse73190_adjacent_post_sort' );