Раз и навсегда разбираемся со ссылками на следующую и предыдущую записи!

Уверен, что так или иначе вы сталкивались с задачей вывода на какой-то конкретной записи ссылок на предыдущую и следующую запись. Далеко за примером ходить не надо — возьмём хотя бы стандартную тему Twenty Fifteen.

Ссылки на следующую и предыдущую записи в теме twentyfifteen

Возможно вы даже знакомы с функциями next_post_link(), previous_post_link() или the_post_navigation() (как раз этой функцией и реализовано в теме Twenty Fifteen.

Каждая из этих функций имеет свои параметры и в какой-то степени довольно гибкая, однако и этого порой хватает не всегда!

Так вот, если вы не можете вписать вашу вёрстку в перечисленные выше функции, я рекомендую вам взглянуть на get_previous_post() (предыдущая запись) и get_next_post() (следующая запись) — дело в том, что эти функции возвращают не просто URL и не просто какой-то HTML-элемент, а целый объект поста, которым уже мы можем распоряжаться как угодно!

Вообще принцип работы функции очень простой:

$pred_post = get_previous_post(); // получили и записали в переменную объект предыдущего поста
echo '<a href="' . get_permalink( $pred_post ) . '">« Назад</a>';

Функцию get_permalink() я использовал для получения ссылки на пост.

Или чуть-чуть усложним:

$pred_post = get_previous_post(); // получили и записали в переменную объект предыдущего поста
echo '<a href="' . get_permalink( $pred_post ) . '" title="К посту: ' . esc_attr( $pred_post->post_title ) . '">« Назад</a>';

Как видите, в примере я добавил всплывающую подсказку через HTML-атрибут title. Возникает вопрос — для чего нам функция esc_attr()? Всё очень просто, она нужна на тот случай, если вдруг в заголовке поста укажут какие-то символы, которые нельзя помещать в HTML-атрибуты, в этом случае функция просто спасёт нашу вёрстку.

И да, у функции есть параметры, связаны они с рубриками, метками и таксономиями, если точнее, то они просто позволяют сделать так, чтобы брался не любой предыдущий/следующий пост, а именно тот, который отмечен точно такой же меткой, что и текущий, или находится точно в такой же рубрике. Например для меток это будет выглядеть следующим образом:

$pred_post = get_previous_post( true, '', 'post_tag' );
// первый параметр равен true - значит ДА, брать посты по тем же меткам
// во втором параметре можно указать через запятую или в массиве ID меток, которые нужно проигнорировать
// третий параметр - название таксономии, как раз для меток это post_tag

Более подробный пример — на видео:

Почему бы для полного счастья ещё и не настроить типы записей?

По умолчанию для ссылок на предыдущий и следующий пост берутся записи такого же типа, что и текущая. А что делать, если мы хотим, чтобы там отображались все типы или допустим какие-то определённые?

Предлагаю хукануть это через functions.php, через get_previous_post_where или get_previous_post_where (или сразу через оба!)

add_action( 'get_previous_post_where', 'misha_posts_and_page', 20 );
add_action( 'get_next_post_where', 'misha_posts_and_page', 20 );
 
function misha_posts_and_page( $where ){
 
	// запрос выглядит "WHERE p.post_date $op %s AND p.post_type = %s $where"
	// самое главное, что параметр $op нифига не передаётся
	// но так как не хочется мутить два похожих хука, я сделаю просто str_replace
	return str_replace(
		array( "p.post_type = 'post'", "p.post_type = 'page'" ),
		"(p.post_type = 'post' OR p.post_type = 'page')",
		$where
	);
 
}

Суть этого хука в том, что после вставки его в functions.php, ссылки на следующую/предыдущую записи у вас начнут работать сразу и для записей и для страниц. Если код вызывает трудности, рекомендую глянуть на документацию функции PHP str_replace() и немного почитать про SQL-запросы.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Комментарии — 2

Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал