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

Функция для вывода последних записей в WordPress

Замена виджету WordPress для вывода последних записей.

Код из этой статьи рабочий, но лучше используйте для этих целей стандартную функцию get_posts().

С помощью функции ниже можно быстро настроить вывод списка последних записей. Функцию можно использовать в любых местах шаблона. Например, когда нужно вывести список последних записей из какой-либо категории на главной странице или наоборот, вывести список последних записей из всех категорий, кроме указанных.

Если использовать get_posts(), или query_posts() для вывода записей, то нужно оформлять код через foreach. Для новичков это не всегда удобно. Функция ниже лишена этого недостатка.

Использование функции

Вставляем функцию в файл темы functions.php или в файл, где мы будем выводить последние записи (например, sidebar.php)

/**
 * Выводит на экрна список последних записей.
 *
 * @param  integer [$post_num = 5]   Количество ссылок
 * @param  string [$format = '']     {avatar} {author}: {date:j.M.Y} - {a}{title}{/a} ({comments})
 * @param  string [$cat = '']        Категории из которых нужно выводить (5,15) или которые нужно исключить (-5,-15),
 *                                   через запятую (одновременно включение и исключение не работает (не имеет смысла) )
 * @param  string [$list_tag = 'li'] Тег списка
 * @param  boolean [$echo = true]    Выводить на экран или возвращать
 *
 * @return string  HTML.
 * @version: 0.1.2
 */
function kama_recent_posts( $post_num = 5, $format = '', $cat = '', $list_tag = 'li', $echo = true ){
	global $post, $wpdb;

	$cur_postID = $post->ID;

	// исключим посты главного запроса (wp_query)
	$IDs = '';
	foreach( $GLOBALS['wp_query']->posts as $post ) $IDs .= $post->ID .',';
	$AND_NOT_IN = ' AND p.ID NOT IN ('. rtrim($IDs, ',') .')';

	$DISTINCT = $SEL = $JOIN = $AND_category = $AND_taxonomy = '';

	if( $cat ){
		$JOIN = "LEFT JOIN $wpdb->term_relationships rel ON ( p.ID = rel.object_id )
			LEFT JOIN $wpdb->term_taxonomy tax ON ( tax.term_taxonomy_id = rel.term_taxonomy_id  ) ";
		$DISTINCT = "DISTINCT";
		$AND_taxonomy = "AND tax.taxonomy = 'category'";
		$AND_category = "AND tax.term_id IN ($cat)";

		// Проверка на исключение категорий
		if( strpos($cat, '-')!==false )
			$AND_category = 'AND tax.term_id NOT IN ('. str_replace( '-','', $cat ) .')';

	}
	// если нужно показать автора
	if( false !== strpos($format, '{author}') ){
		$JOIN .= " LEFT JOIN $wpdb->users u ON ( p.post_author = u.ID )";
		$SEL = ", u.user_nicename AS author, u.user_email, u.user_url";

		// если нужно показать аватар (gavatar)
		if( strpos($format, '{avatar}')!==false )
			$av = "<img src='http://www.gravatar.com/avatar/%1\$s?s=25' alt='' />";
	}

	$sql = "SELECT $DISTINCT p.ID, post_title, post_date, comment_count, guid, post_author $SEL
	FROM $wpdb->posts p $JOIN
	WHERE post_type = 'post' AND post_status = 'publish' $AND_category $AND_taxonomy $AND_NOT_IN
	ORDER BY post_date DESC LIMIT $post_num";
	$results = $wpdb->get_results($sql);

	if( ! $results )
		return false;

	$out = '';
	$x = '';
	preg_match( '~\{date:(.*?)\}~', $format, $date_m );
	foreach( $results as $pst ){
		$x = ( $x == 'li1' ) ? 'li2' : 'li1';
		if ( $pst->ID == $cur_postID ) $x .= " current-item";

		$a = '<a href="'. get_permalink($pst->ID) .'" title="'. esc_attr($pst->post_title) .'">';

		if( $format ){
			$avatar = isset($av) ? sprintf( $av, md5($pst->user_email) ) : '';
			$date = apply_filters('the_time', mysql2date($date_m[1], $pst->post_date));
			$Sformat = str_replace( $date_m[0], $date, $format);
			$Sformat = str_replace(
				array('{title}',                   '{a}', '{/a}', '{author}',             '{comments}',         '{avatar}'),
				array( esc_html($pst->post_title), $a,    '</a>', esc_html($pst->post_author), $pst->comment_count,  $avatar   ),
				$Sformat
			);
		}
		else
			$Sformat = $a . esc_html($pst->post_title) .'</a>';

		$out .= "\n<$list_tag class='$x'>{$Sformat}</$list_tag>";
	}

	if( $echo ) echo $out;
	return $out;
}

Там, где нужно вывести последние записи, вызываем функцию используя, следующий код:

<ul>
	<?php kama_recent_posts (5); ?>
</ul>

// где, 5 это количество выводимых записей.

Дополнительные возможности функции

  1. Можно настроить формат вывода (формат передается во втором параметре $format = '');
  2. Можно, исключить или наоборот, включить какие-либо категории;
  3. Можно изменить тег списка (вместо li списка использовать, например, div).
Для настройки формата вывода используйте:
  • {comments} - покажет колличество комментариев у статьи;
  • {title} - заголовок статьи;
  • {date:j.M.Y} - дата в формате j.M.Y (11.Апр.2010);
  • {a} и {/a} - тег ссылки. Открывается и закрывается.

Вызов будет таким:

<ul>
	  <?php kama_recent_posts (5, '{a}{title}{/a} ? {date:j.M.Y} // {comments}');  ?>
</ul>
// выведет список в формате - <li class='li1'><a href='http://ссылка' title='Заголовок статьи'>Заголовок статьи</a> ? дата // количество комментариев</li>
Пример исключения или включения каких-либо категорий:

Для исключения категорий в третьем параметре передаем ID категорий через запятую, со знаком "минус" (пример: -5,-15,-20)

Для вывода записей только из указанных категорий (включения категорий) передаем в третьем параметре ID категорий через запятую (пример: 5,15,20)

<ul>
	  <?php kama_recent_posts (5, '', '5,15,20');  ?>
</ul>
// выведет список последних записей только из категорий, ID которых равны 5, 15 или 20

<ul>
	  <?php kama_recent_posts (5, '', '-5,-15,-20');  ?>
</ul>
// выведет список последний записей из всех категорий, кроме 5, 15 или 20

Так же, как и обычно в функциях WordPress, к тегу li добавляется сласс current-item (<li class='li1 current-item'></li>), если ID просматриваемой записи равен ID записи из списка, т.е. если мы просматривает одну из записей, находящихся в списке. Используя этот класс, можно визуально выделить запись в списке, через css.

152 коммента
Полезные 2 Вопросы 1 Все
  • @ Андрей cайт: bdseo.ru

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

    Ответить2.5 года назад #
    • Kama5409

      Это не плагин - это мой код. Там все сложно с введением маркдауна все совсем сложно... Задавай конкретные вопросы подскажу...

      Коротко так:

      Подсветка с помощью hightlightjs

      Код вставляется в тройные ` которые затем превращаются в PRE тег и внутри все спец символы HTML заменяются на сущности.

      Ответить2.5 года назад #
      • @ Андрей cайт: bdseo.ru

        спс, в целом я сам могу написать функции и теги, но думал что уже есть готовый плагин smile

        Ответить2.5 года назад #
  • Вадим

    Привет, Тимур. Подскажи, пожалуйста, какой можно использовать код для вывода 5 последних записей на блоге (участвуют все категории), кроме уже открытой статьи, чтобы не было ссылки самой на себя.

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

    1
    Ответить2.5 года назад #
    • Ростислав

      Тоже интересует вопрос

      Ответить2.2 года назад #
    • Kama5409

      Для вывода последних записей проще использовать get_posts(), чтобы исключить тек. запись, укажите её ID в параметре exclude.

      Пример вывода 10 послед. записей, с исключением текущей:

      <?php
      global $post;
      $lastposts = get_posts( array('posts_per_page'=>10, 'exclude'=>$post->ID ) );
      foreach( $lastposts as $post ){
      	setup_postdata($post);
      	?>
      	<div>
      		<?php the_date(); ?>
      		<br />
      		<?php the_title(); ?>
      		<?php the_excerpt(); ?>
      	</div>
      	<?php
      }
      wp_reset_postdata();
      Ответить2.2 года назад #
  • campusboy2856 cайт: www.youtube.com/c/wpplus

    Прелесть get_post, что она кеширует результаты, а в этой функции кеширование я не вижу. Может стоит добавить? Или я глупость сморозил? smile Тимур, поправь меня пожалуйста, если не прав.

    Ответить2.4 года назад #
    • Kama5409

      get_post() не кэширует запрос, а кэширует данные записей, причем только для текущей генерации, если только не установлен плагин постоянного объектного кэширования, которого в 99% нет... В общем по большому счету ничего не кэишруется...

      Тут есть свои плюсы и минусы, суть этого поста и функции, стать основой для изучения и возможно вывода.

      Сейчас запустил проверки (вывод полностью одинаковый) - это факты:

      kama_recent_posts() - 1/500 повторений - 0.00382 сек./0.39681 сек.

      get_posts() - 1/500 повторений - 0.00799 сек./0.87335 сек.

      Т.е. get_posts в 2 раза проигрывает. Это без объектного кэширования, с ним, я думаю, get_posts() выиграет. Но если добавить его в эту функцию, там 3 строчки всего, тогда она выиграет во много раз...

      Вообще все это конечно мелочи, тут больше нужно на удобство программирования ориентироваться, и если нужен какой-то отличный вывод от того что предлагает эта функция, то правильнее использовать get_posts()...

      Ответить2.4 года назад #
  • Димонтий

    Блин, чувак, это просто невероятно! Только у меня возникает какой-то нестандартный вопрос по водрпрессу, как ты его уже решил! Всегда нахожу у тебя на сайте готовые решения! Спасибище тебе огромное!

    2
    Ответить1.5 год назад #
  • Михаил cайт: trapeznaya.ucoz.ru

    Здравствуйте Kama. А подскажите как сделать список например 5 последних редакций, как у вас в сайдбаре, т.е. не последние записи выводить, а последние которые редактировались. Спасибо!

    Ответить1.3 год назад #
    • Kama5409

      У меня это такой код:

      // Последние отредактированные записи
      $editted_list = [];
      // Создадим новую функцию которая добавит условие where в запрос
      function __temp_filter_where( $where = '' ){
      	$where .= " AND post_date != post_modified ";
      	return $where;
      }
      add_filter('posts_where', '__temp_filter_where' );
      
      $edited = get_posts([
      	'posts_per_page' => 15,
      	'date_query'     => ['after'=>'1 weeks ago', 'column'=>'post_modified' ],
      	'post_type'      => ['post','func','hook'],
      	'orderby'        => 'post_modified',
      	'order'          => 'DESC',
      	'suppress_filters' => 0,
      ]);
      remove_filter('posts_where', '__temp_filter_where' );
      
      if( $edited ){
      	foreach( $edited as $pst ){
      		$editted_list[] = '<a href="'. get_permalink($pst) .'">'. esc_html($pst->post_title) .'</a>';
      	}
      }
      
      if( $editted_list ){
      	$out .= '
      	<ul class="li_2 sb_block last_edited">
      		<span class="block__icon"><i class="dashicons dashicons-edit"></i></span>
      		<li>'. implode('</li><li>', $editted_list ) .'</li>
      	</ul>
      	';
      }
      Ответить1.3 год назад #
  • Никак не могу добавить краткое описание и дату sad

    $e_x = '' . esc_html($pst->the_excerpt ) . '';
    $date = apply_filters('the_time', mysql2date($date_m[1], $pst->post_date));

    Строки возвращают пустые поля. Подскажите, пожалуйста

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

      не $pst->the_excerpt а $pst->post_excerpt. С датой все норм, должно работать... unknw

      Ответить1.1 год назад #
  • @ Максим

    Тимур хочу для последних записей задать стили, но мои изменения никак не реагируют:

    .li1{background-color: #666666;}
    .li2{background-color: #336699;}

    Что я делаю не так?

  • @ Саня cайт: people.bl.ee

    Подскажите, пожалуйста, какие места в коде нужно поменять, чтобы выводились НЕ логины авторов, а их никнэймы - display_name? Пробовал в 3-х местах заменить {author} на {display_name} - результата не дало.

    3
    Ответить2 месяца назад #
Здравствуйте, !     Войти . Зарегистрироваться