WordPress: Выводим блоки рубрик с сортировкой по дате последнего поста

Выводим блоки рубрик с сортировкой по дате последнего поста на WordPress Задумка отойти от стандартного вывода последних постов на главной странице этого блога появилась у меня уже очень давно, но я все никак не мог придумать вариант, который бы устроил, да и отсутствие у меня дизайнерских способностей, как обычно, все осложняло. Наконец-то недавно я созрел и решил сделать следующее — вывести блоки рубрик, в которых будет представлен список последних постов из этих рубрик.

Но мне хотелось не просто вывести эти блоки в каком-то произвольно порядке, а чтобы они автоматически сортировались в зависимости от даты последних записей в этих рубриках. Т.е., к примеру, если мой последний пост опубликован в рубрике «CSS», а предпоследний — в рубрике «jQuery», то на главной первым будет отображаться блок рубрики «CSS», вторым, соответственно, «jQuery» и так далее. Т.е. появляется динамичность этих блоков.

Как оказалось, решить подобную задачу не так и сложно. Собственно, готовым php-кодом я и делюсь ниже. Наверняка кому-нибудь да пригодится.

PHP-код

Вот весь основной код с моими комментариями:

<?php
// берем последние 30 постов сайта
$loop = new WP_Query('posts_per_page=30');

if ($loop->have_posts()) {
	// проходимся по каждому из полученных постов
	while ($loop->have_posts()) { $loop->the_post();

		// считываем данные о рубрике поста
		$category = get_the_category($loop->post->ID);

		// получаем идентификатор рубрики и добавляем его в массив
		$array1[] = $category[0]->cat_ID;
	}

	// удаляем из полученного массива повторяющиеся ID рубрик
	$array1 = array_unique($array1);

	// создаем 2-й массив, в котором указываем ID рубрик, последние записи из которых мы хотим вывести
	$array2 = array(1,10,45,107);

	// сравниваем 2 массива, чтобы в списке ID рубрик, полученных из последних 30 постов, остались только те, которые мы указали в массиве $array2, и создаем новый (3-й) массив
	// это действие необходимо для того, чтобы сохранилась сортировка рубрик по дате последнего поста в них
	$array = array_intersect($array1, $array2);
}
// создаем счетчик
$i = 0;

// запускаем цикл, который выводит блоки рубрик
foreach ($array as $cat) { $i++;

	// получаем данные рубрики
	$category = get_category($cat);
?>
	<div class="column<?php /* добавляем класс .odd к каждому нечетному блоку рубрики */ if ($i%2 == true) echo ' odd'; ?>">
		<h2><?php echo $category->name; ?></h2>
	<?php
		// берем последние 7 записей из рубрики
		$loop = new WP_Query('posts_per_page=7&cat=' . $cat);
	?>
	<?php if ($loop->have_posts()) { ?>
		<ul>
		<?php
			// запускаем цикл, который выводит последние записи из рубрики
			while ($loop->have_posts()) { $loop->the_post();
		?>
			<li><?php the_time('d.m.Y') ?> <a href="<?php the_permalink() ?>"><?php the_title(); ?></a></li>
		<?php } ?>
	<?php } ?>
		</ul>
		<a href="<?php echo get_category_link($category->cat_ID); ?>">Все статьи рубрики "<?php echo $category->name; ?>"</a>
	</div><!-- .column -->
<?php } ?>

В случае, если вам необходимо, чтобы выводились вообще все рубрики, которые есть на сайте, то в вышеуказанный код внесите следующие изменения:

  1. Удалите эти строки:

    $array2 = array(1,10,45,107);
    $array = array_intersect($array1, $array2);
    
  2. Замените эту строку:

    $array1 = array_unique($array1);
    

    на такую:

    $array = array_unique($array1);
    

Прошу обратить внимание на следующий момент. Если вы в массиве $array2 = array(...) указали определенную рубрику, но ее блок не выводится, значит среди последних 30 постов (которое задано в самой первой строке) не было постов, опубликованных в этой самой рубрике. Значит вам нужно вместо 30 поставить число побольше.

CSS-код

Теперь остается добавить следующие стили, чтобы блоки отображались в 2 столбца:

.column {
	float: right;
	width: 48%;
}
.column.odd {
	clear: both;
	float: left;
}

Ширину (48%) при необходимости поменяйте на свою.

* * *

Всегда важно размещать свой сайт на быстром хостинге, где ваши статические файлы css будут быстро загружаться. Хостинг wordpress можно заказать в компании RX-NAME.

Комментарии (53)
  1. 1

    Спасибо за статью, самому в этом деле сложнова-то разобраться.

  2. 2

    Боже, какой ужас вы предлагаете. Не вещь конечно интересная, но какую нагрузку на сервер даст! Это же куча запросов к БД. Может кто и рискнёт, но лучше сразу подумать, а оно надо?

  3. 12

    Добрый день, Дмитрий. Не подскажете, что может быть, если рубрики отображают контент из других рубрик?

  4. 17

    Дмитрий, подскажите пожалуйста — этот код на пхп надо вставлять в index.php или в другой файл?

  5. 20

    Да бл* он не умеет вытаскивать подрубрики, т.е так
    -Уроки фотошоп
    -Работа с текстом
    -работа с фото
    Ставлю чтоб вытащить рубрики с Уроки фотошоп, но там нет уроков, они толко в подрубриках , он их не вытаскивает не знаешь как это сделать?

  6. 24

    Ну иили тогда как можно выташить определенную рубрику т.е без твоего кода , отдельно например рубрику Уроки фотошоп с последними 5 записями

  7. 27

    ты не знаешь как в архиве записей не вытаскивать все записи а записи одной рубрики.
    К примеру надо что бы в архиве записей отображались только записи из рубрики Новости.
    Если знаешь какую нибудь ссылку с реализацией дай пожалуйста )

  8. 34
    Лиза

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

  9. 36

    Для Лизы….. http://www.yourinspirationweb.com/en/wordpress-plugin-featured-posts-with-thumbnails-highlighting-your-best-articles/ Плагин Featured Posts with thumbnails.

  10. 37

    Дима ты не знаешь в чем может быть проблема, после установки вот этого списка кода перестает работать пагинация:

     <?php 
     $order = "&orderby=date&order=DESC"; 
     $s2 = ' selected="selected"'; 
     if ($_POST['select'] == 'title') { $order = "&orderby=title&order=ASC"; $s1 = ' selected="selected"'; $s2 = ''; } 
     if ($_POST['select'] == 'newest') { $order = "&orderby=date&order=DESC"; $s2 = ' selected="selected"'; } 
     if ($_POST['select'] == 'oldest') { $order = "&orderby=date&order=ASC"; $s3 = ' selected="selected"'; $s2 = ''; } 
     if ($_POST['select'] == 'modified') { $order = "&orderby=modified"; $s4 = ' selected="selected"'; $s3 = ''; } 
     ?> 
     
     <form method="post" id="order"> 
     Сортировать: 
     <select name="select" onchange='this.form.submit()' style="width:200px"> 
     <option value="title"<?=$s1?>>по заголовку</option> 
     <option value="newest"<?=$s2?>>по дате (сначала новые)</option> 
     <option value="oldest"<?=$s3?>>по дате (сначала старые)</option> 
     <option value="modified"<?=$s4?>>по дате изменения</option> 
     </select> 
     </form> 
     <?php query_posts($order); ?> 
  11. 41
    Влад

    Спасибо за отличное решение. Выводит все в нужном формате, но проблема — выводит одно и то же 4 раза! Подскажите, как от этого избавиться?

    • 42

      Не знаю. У меня ничего не дублируется. Скорее всего, что-то неправильно сделали.

      • 43
        Влад

        Может, вот здесь что-то не так:

        <?php get_header(); ?>
        	<?php if( is_home() && ! is_paged() ) : ?>
        		<?php if( pinboard_get_option( 'slider' ) ) : ?>
        			<?php get_template_part( 'slider' ); ?>
        		<?php endif; ?>
        		<?php get_sidebar( 'wide' ); ?>
        		<?php get_sidebar( 'boxes' ); ?>
        	<?php elseif( ( is_home() && is_paged() ) || ( ! is_home() && pinboard_get_option( 'location' ) ) ) : ?>
        		<?php pinboard_current_location(); ?>
        	<?php endif; ?>
        	<div id="container">
        		<section id="content" <?php pinboard_content_class(); ?>>
        			<?php if( is_category( pinboard_get_option( 'portfolio_cat' ) ) || ( is_category() && cat_is_ancestor_of( pinboard_get_option( 'portfolio_cat' ), get_queried_object() ) ) ) : ?>
        				<?php pinboard_category_filter( pinboard_get_option( 'portfolio_cat' ) ); ?>
        			<?php endif; ?>
        			<?php if (have_posts()) : ?>
        				<div class="entries">
        					<?php while( have_posts() ) : the_post(); ?>
        						<?php get_template_part( 'content-work', get_post_format() ); ?>
        					<?php endwhile; ?>
        				</div><!-- .entries -->
        				<?php pinboard_posts_nav(); ?>
        			<?php else : ?>
        				<?php pinboard_404(); ?>
        			<?php endif; ?>
        		</section><!-- #content -->
        		<?php if( 'no-sidebars' != pinboard_get_option( 'layout' ) && 'full-width' != pinboard_get_option( 'layout' ) && ! is_category( pinboard_get_option( 'portfolio_cat' ) ) && ! ( is_category() && cat_is_ancestor_of( pinboard_get_option( 'portfolio_cat' ), get_queried_object() ) ) ) : ?>
        			<?php get_sidebar(); ?>
        		<?php endif; ?>
        		<div class="clear"></div>
        	</div><!-- #container -->
        <?php get_footer(); ?>
  12. 45
    Андрей

    Извините, что не по теме, но все-таки…

    У меня почему-то не работает такая простая, казалось бы, штука: post_is_in_descendant_category?

    Я пока пользуюсь этой конструкцией:

    if (in_category (array ( ’87’, ’99’ ))) {

    include (TEMPLATEPATH.’/loop-flower.php’);

    } elseif (in_category (array ( ’96’, ‘104’ ))) {

    include (TEMPLATEPATH.’/loop-care.php’);

    } else {

    include (TEMPLATEPATH.’/loop-single.php’);

    }

    Но по при увеличении количества дочерних рубрик это перестанет быть удобным. Подскажите, что не так? Как правильно прописать код?

  13. 46

    Кстати, очень удобный вывод новостей. Но при большом количестве категорий становится неудобно.

  14. 47

    Дмитрий, добрый день!
    Прочитав вашу статью в принципе все понятно, но когда я вставляю ваш код в index.php ничего не меняется.
    Код index.php

    <?php get_header(); ?>
    
    <div class="main <?php echo alx_layout_class(); ?>">
    	<div class="main-inner group">
    		
    		<section class="content">
    		
    			<?php get_template_part('inc/page-title'); ?>
    			
    			<div class="pad group">
    				<?php get_template_part('inc/featured'); ?>
    				
    				<?php if ( have_posts() ) : ?>
    				
    					<div class="post-list group">
    						<?php $i = 1; echo '<div class="post-row">'; while ( have_posts() ): the_post(); ?>
    						<?php get_template_part('content'); ?>
    						<?php if($i % 2 == 0) { echo '</div><div class="post-row">'; } $i++; endwhile; echo '</div>'; ?>
    					</div><!--/.post-list-->
    				
    					<?php get_template_part('inc/pagination'); ?>
    					
    				<?php endif; ?>
    				
    			</div><!--/.pad-->
    			
    		</section><!--/.content-->
    		
    		<?php get_sidebar(); ?>
    		
    	</div><!--/.main-inner-->
    </div><!--/.main-->
    
    <?php get_footer(); ?>

    Огромная просьба подскажите пожалуйста в какое место нужно вставить Ваш код или как его преобразовать, чтобы вывести 4 блока (4 рубрики) на галвной.

    Заранее спасибо!

  15. 51
    Павел

    Привет, твой код отлично работает для стандартной таксономии category.
    А если мне нужно делать почти тоже самое только из своей таксономии ?

  16. 53
    Александр

    Интересно.
    А нет у вас статейки как в 3-х блоках вывести 3 отдельные рубрики?