WordPress как на ладони
wordpress jino

get_adjacent_post() WP 2.5.0

Получает объект соседнего (следующего или предыдущего) поста.

Не возможно получить одновременно следующий и предыдущий посты.

Хуки из функции:
Возвращает

Null/Объект/пустая строка.

  • Объект записи, в случае успеха;
  • Null, если глобальная переменная $post не установлена;
  • Пустую строку, если нет подходящего поста.

Использование

get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy );
$in_same_term(логический)
Должен ли пост находиться в той же рубрике. true - получать посты из той же рубрики.
По умолчанию: false
$excluded_terms(строка)
Из каких категорий посты получать не нужно. Указываем ID категорий, через запятую.
По умолчанию: ''
$previous(логический)
true - получать предыдущий пост. false - получать следующий пост.
По умолчанию: true
$taxonomy(строка)
Название таксономии в которой нужно искать пред./след. запись, когда включен параметр $in_same_term.
По умолчанию: 'category'

Возвращаемые данные

(объект) Пример элементов объекта, которые возвращает функция:

[ID] => 25
	[post_author] => 1
	[post_date] => 2010-04-05 04:24:04
	[post_date_gmt] => 2010-04-05 00:24:04
	[post_content] => Если у вас внезапно есть, что обсудить, пройдитесь клавиатурой по форме ниже:
	[post_title] => Обратная связь
	[post_excerpt] =>
	[post_status] => publish
	[comment_status] => closed
	[ping_status] => closed
	[post_password] =>
	[post_name] => contacts
	[to_ping] =>
	[pinged] =>
	[post_modified] => 2010-08-16 17:41:20
	[post_modified_gmt] => 2010-08-16 13:41:20
	[post_content_filtered] =>
	[post_parent] => 0
	[guid] => http://wp-kama.ru/contacts
	[menu_order] => 0
	[post_type] => page
	[post_mime_type] =>
	[comment_count] => 0

Примеры

Выведем на экран ссылку на следующий пост:

$next_post = get_adjacent_post(0, '', 0);
if( $next_post )
	echo '<a href="'. get_permalink($next_post->ID) .'">'. $next_post->post_title .'</a>';

Выведем на экран ссылку на предыдущий пост:

$prev_post = get_adjacent_post();
if( $prev_post )
	echo '<a href="'. get_permalink($prev_post->ID) .'">'. $prev_post->post_title .'</a>';

Код get adjacent post: wp-includes/link-template.php WP 4.9

<?php
function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
	global $wpdb;

	if ( ( ! $post = get_post() ) || ! taxonomy_exists( $taxonomy ) )
		return null;

	$current_post_date = $post->post_date;

	$join = '';
	$where = '';
	$adjacent = $previous ? 'previous' : 'next';

	if ( $in_same_term || ! empty( $excluded_terms ) ) {
		if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) {
			// back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
			if ( false !== strpos( $excluded_terms, ' and ' ) ) {
				_deprecated_argument( __FUNCTION__, '3.3.0', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) );
				$excluded_terms = explode( ' and ', $excluded_terms );
			} else {
				$excluded_terms = explode( ',', $excluded_terms );
			}

			$excluded_terms = array_map( 'intval', $excluded_terms );
		}

		if ( $in_same_term ) {
			$join .= " 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";
			$where .= $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );

			if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
				return '';
			$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );

			// Remove any exclusions from the term array to include.
			$term_array = array_diff( $term_array, (array) $excluded_terms );
			$term_array = array_map( 'intval', $term_array );

			if ( ! $term_array || is_wp_error( $term_array ) )
				return '';

			$where .= " AND tt.term_id IN (" . implode( ',', $term_array ) . ")";
		}

		/**
		 * Filters the IDs of terms excluded from adjacent post queries.
		 *
		 * The dynamic portion of the hook name, `$adjacent`, refers to the type
		 * of adjacency, 'next' or 'previous'.
		 *
		 * @since 4.4.0
		 *
		 * @param string $excluded_terms Array of excluded term IDs.
		 */
		$excluded_terms = apply_filters( "get_{$adjacent}_post_excluded_terms", $excluded_terms );

		if ( ! empty( $excluded_terms ) ) {
			$where .= " AND p.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships tr LEFT JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.term_id IN (" . implode( ',', array_map( 'intval', $excluded_terms ) ) . ') )';
		}
	}

	// 'post_status' clause depends on the current user.
	if ( is_user_logged_in() ) {
		$user_id = get_current_user_id();

		$post_type_object = get_post_type_object( $post->post_type );
		if ( empty( $post_type_object ) ) {
			$post_type_cap    = $post->post_type;
			$read_private_cap = 'read_private_' . $post_type_cap . 's';
		} else {
			$read_private_cap = $post_type_object->cap->read_private_posts;
		}

		/*
		 * Results should include private posts belonging to the current user, or private posts where the
		 * current user has the 'read_private_posts' cap.
		 */
		$private_states = get_post_stati( array( 'private' => true ) );
		$where .= " AND ( p.post_status = 'publish'";
		foreach ( (array) $private_states as $state ) {
			if ( current_user_can( $read_private_cap ) ) {
				$where .= $wpdb->prepare( " OR p.post_status = %s", $state );
			} else {
				$where .= $wpdb->prepare( " OR (p.post_author = %d AND p.post_status = %s)", $user_id, $state );
			}
		}
		$where .= " )";
	} else {
		$where .= " AND p.post_status = 'publish'";
	}

	$op = $previous ? '<' : '>';
	$order = $previous ? 'DESC' : 'ASC';

	/**
	 * Filters the JOIN clause in the SQL for an adjacent post query.
	 *
	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
	 * of adjacency, 'next' or 'previous'.
	 *
	 * @since 2.5.0
	 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
	 *
	 * @param string  $join           The JOIN clause in the SQL.
	 * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
	 * @param array   $excluded_terms Array of excluded term IDs.
	 * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
	 * @param WP_Post $post           WP_Post object.
	 */
	$join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post );

	/**
	 * Filters the WHERE clause in the SQL for an adjacent post query.
	 *
	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
	 * of adjacency, 'next' or 'previous'.
	 *
	 * @since 2.5.0
	 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
	 *
	 * @param string  $where          The `WHERE` clause in the SQL.
	 * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
	 * @param array   $excluded_terms Array of excluded term IDs.
	 * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
	 * @param WP_Post $post           WP_Post object.
	 */
	$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post );

	/**
	 * Filters the ORDER BY clause in the SQL for an adjacent post query.
	 *
	 * The dynamic portion of the hook name, `$adjacent`, refers to the type
	 * of adjacency, 'next' or 'previous'.
	 *
	 * @since 2.5.0
	 * @since 4.4.0 Added the `$post` parameter.
	 * @since 4.9.0 Added the `$order` parameter.
	 *
	 * @param string $order_by The `ORDER BY` clause in the SQL.
	 * @param WP_Post $post    WP_Post object.
	 * @param string  $order   Sort order. 'DESC' for previous post, 'ASC' for next.
	 */
	$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1", $post, $order );

	$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
	$query_key = 'adjacent_post_' . md5( $query );
	$result = wp_cache_get( $query_key, 'counts' );
	if ( false !== $result ) {
		if ( $result )
			$result = get_post( $result );
		return $result;
	}

	$result = $wpdb->get_var( $query );
	if ( null === $result )
		$result = '';

	wp_cache_set( $query_key, $result, 'counts' );

	if ( $result )
		$result = get_post( $result );

	return $result;
}

Cвязанные функции

Из метки: Связи

Еще из раздела: Навигация

get_adjacent_post 7 комментариев
  • samizdam cайт: samizdam.spb.ru @

    Немного лестных слов smile Перевёл тут один проект на WP, пришлось поработать основательно напильником, чтобы добиться всего что хотел, ну и плагинов уйму перепробовать. Ваш справочник по функциям на русском — просто незаменимый источник информации при доработке шаблона!

    3
    Ответить4.9 года назад #
  • campusboy1871 cайт: www.youtube.com/c/wpplus

    С этой функцией и её производными надо проверять возвращаемый результат, так как если запись самая последняя или, наоборот, первая - один из вариантов будет пустой и при echo выдаст notice + битую ссылку, соответственно. Ни один пример здесь это не учитывает, потому что они показательные, но нужно об этом помнить.

    1
    Ответить1.1 года назад #
    • Kama4558

      Ща дополню примеры. Спасибо!

      1
      Ответить1.1 года назад #
      • campusboy1871 cайт: www.youtube.com/c/wpplus

        Может быть пригодится мой пример, я его всегда использую. Он не идеальный, решает только мою задачу, но может пригодится другим, так как не в первый раз вижу вопрос, как закольцевать это дело. То есть, если запись последняя - отобразить ссылку на запись с "другого конца", и наоборот.

        Так вот:

        /**
         * Выводит ссылку (HTML тег A) на смежные записи (следующая/предыдущая).
         * 
         * При отсутствии смежной записи выводит запись с противоположного конца рубрики. Работает в пределах той рубрики, где находится сама запись.
         *
         * @param string $course принимает значение next/prev.
         */
        function da_the_adjacent_post_link( $course = '' ){
          global $post;
          $course = ( $course == 'prev' ) ? true : false;
          $order  = ( $course ) ? 'DESC' : 'ASC';
          $class  = ( $course ) ? 'prev' : 'next';
        
          $link = get_adjacent_post_link( '%link', '%title', true, '', $course );
        
          if ( ! $link ){
        	$term = get_the_terms( $post->ID, 'category' );
        	$term = $term[0];
        	$article = get_posts([
        	  'numberposts' => 1,
        	  'exclude'     => $post->ID,
        	  'category'    => $term->term_id,
        	  'order'       => $order
        	]);
        
        	if ( empty($article) )
        	  return false;
        	else
        	  $article = $article[0];
        
        	$link = sprintf( '<a href="%s" rel="%s">%s</a>', get_the_permalink($article->ID), $class, $article->post_title );
          }
        
          echo $link;
        }

        По хорошему, нужно бы использовать какой хук для get_adjacent_post и к нему подобное мастырить, а также желательно было бы предусмотреть передачу всех параметров, которые передаются в get_adjacent_post, но дело дошло только до такого варианта у меня, нужды не было делать большее smile

        1
        Ответить1.1 года назад #
        • Kama4558

          Глянул одним глазом, чет нет подходящих хуков. Не мало хуков, только какие-то бестолковые все - странно... Добавлю твою функцию в примеры. Хотя конечно через хуки бы это сделать, а то как-то не круто совсем... Потом еще гляну если не забуду...

          Спасибо как всегда!

          АП: Добавил в примеры get_adjacent_post_link()

          Ответить1.1 года назад #
  • Андрей

    Из каких категорий посты получать не нужно. Указываем ID постов, через запятую.

    Наверно "указываем ID категорий через запятую".

    Ответить4 месяца назад #

Здравствуйте, !

Ваш комментарий