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 } ?>
В случае, если вам необходимо, чтобы выводились вообще все рубрики, которые есть на сайте, то в вышеуказанный код внесите следующие изменения:
-
Удалите эти строки:
$array2 = array(1,10,45,107); $array = array_intersect($array1, $array2);
-
Замените эту строку:
$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.
Комментарии (55)
Спасибо за статью, самому в этом деле сложнова-то разобраться.
Боже, какой ужас вы предлагаете. Не вещь конечно интересная, но какую нагрузку на сервер даст! Это же куча запросов к БД. Может кто и рискнёт, но лучше сразу подумать, а оно надо?
Да, я совсем забыл написать про это. В вопросах оптимизации запросов я совсем не разбираюсь, поэтому, конечно, код может быть совсем плохим. Но у меня стояла задача и нужно было как-то ее решить, и как смог, так и сделал.
По крайней мере на этом сайте нагрузка будет не сильная, т.к. используется кэширование.
По сути здесь было бы сложно придумать что-то иное. Да, кэширование это конечно хорошо, но всё равно идёт же хоть и раз в определённый период, но приличное количество запросов за раз. В принципе, можно распределить нагрузку… но это такой гемор. В общем, если нужно решить задачу и есть ресурсы, то почему бы и нет.
У меня на сайте (DLE) стоял неудачный модуль древовидных комментариев – 1 запрос на каждый комментари + 2 запроса на построение дерева. Итого на одной из страниц было 190+ запросов (без кеширования). И ничего, сайт вполне себе нормально жил на витруальном хостинге.
Дима
Не совсем ожидаемое поведение блоков. Вчера блок программы был первым, сегодня – WordPress. Вводит в заблуждение постоянных посетителей))
Ну раз для тебя это так важно, то теперь ты знаешь о том, что они меняются местами =)
Ну я лишь на мгновение смутился)) а у неподготовленного мозга это может вызвать зависание )
Интересная вешь!! Что обновленные блоки будут находиться первее. Спасибо за инструкцию)
Тут всё зависит от хостинга. У меня например виртуальный с соответствующими лимитами.
У Димы, как я понял, решение сортирует по дате последнего поста. Нюанс и в том, что каких-то категорий в поледних 30 постах может и не быть. Плюс перевесы могут быть в какой-то категории выдаст больше, а в какой-то меньше постов.
Лень разбираться в деталях, я бы просто сделал выборку всех категорий, а потом к каждой подвыборку постов. Наверное нюансы поставленного задания или что-то в этом роде.
Пользуйтесь кешированием ;)
А почему бы не воспользоваться каким-нибудь плагином кеширования? Вполне актуально – страница меняется только при добавлении материала, будет сгенерирована раз в день или после изменений. Нагрузка если и будет, то только несколько раз в день.
Добрый день, Дмитрий. Не подскажете, что может быть, если рубрики отображают контент из других рубрик?
Единственный вариант, который я вижу – если статья опубликована одновременно в нескольких рубриках.
Все статьи чётко распределены по рубрикам: фильмы, музыка и т.д. А что отвечает за вывод статей в рубриках?
Если честно, в фильмах я ещё кое-что понимаю, а вот в Вордпресс – нет :)
Проблема была в плагине Simle Tags.
Спасибо что сказал в чем проблема а то я щас тоже буду полностью дизайн и функционал менять и у меня этот плагин Simple Tags стоит )) Буду знать если будут глюки )))
Дмитрий, подскажите пожалуйста – этот код на пхп надо вставлять в index.php или в другой файл?
В index.php, либо home.php.
спасибо, попытаемся!
Да бл* он не умеет вытаскивать подрубрики, т.е так
-Уроки фотошоп
-Работа с текстом
-работа с фото
Ставлю чтоб вытащить рубрики с Уроки фотошоп, но там нет уроков, они толко в подрубриках , он их не вытаскивает не знаешь как это сделать?
WordPress устроен так, что при заходе в рубрику он показывает в том числе и записи из подрубрик.
Какую то хрень написал выше,
Щас изложу по логичнее.
Есть основная рубрика Уроки фотошоп в ней нет статей, т.к статьи размещаются в подрубриках работа с текстом, работа с фото, и т.д. И я ставлю id рубрики Уроки фотошоп но ничего не выводится , не ну это логично там же нет записей только в подрубриках, а как сделать так чтобы он из этой рубрики Уроки фотошоп выводил записи подрубрик?
Может быть записи из этих рубрик не попадают в диапазон, указанный в первой строке кода (30). Попробуй увеличить число.
Записи из подрубрик выводиться должны, я проверил.
Ну иили тогда как можно выташить определенную рубрику т.е без твоего кода , отдельно например рубрику Уроки фотошоп с последними 5 записями
3 – количество записей
45 – рубрика
О супер работает щас доделаю и все. Спасибо огромное реально помого. ))
ты не знаешь как в архиве записей не вытаскивать все записи а записи одной рубрики.
К примеру надо что бы в архиве записей отображались только записи из рубрики Новости.
Если знаешь какую нибудь ссылку с реализацией дай пожалуйста )
Я же выше дал тебе код.
нет это не то
А как из изменить это кода, чтоб был вывод на главной как у вас, но блоки не менялись местами при новой публикации?
В этом случае мою функцию не стоит использовать. Вам нужно сделать несколько циклов c помощью query_posts().
Ага, я вчера начал так делать. Хочу сделать что то похожее как у вас на главной. Для этого мне нужно сделать несколько таких блоков, я правильно понимаю?
Вроде все нормально работает, кроме одной мелочи, почему то дублируется последняя ссылка из 5 ссылок в блок “Все статьи рубрики”. Может я как то не правильно цикл закрыл или не до закрыл? Причем в исходном коде ее нет, а есть только если нажать “Исследовать элемент”
Заранее благодарю.
отбой, ошибка найдена, не закрыл
Здравствуйте. Подскажите, а нельзя ли в некоторых опубликованных заметках прописать какой код или наоборот, убрать его, чтобы она не выходила на главную страницу, куда выводятся все новые опубликованные записи? То есть, чтобы я сама могла выбирать, какая из записей должна появиться на главной.
К сожалению, не знаю, как такое провернуть.
Для Лизы….. http://www.yourinspirationweb.com/en/wordpress-plugin-featured-posts-with-thumbnails-highlighting-your-best-articles/ Плагин Featured Posts with thumbnails.
Дима ты не знаешь в чем может быть проблема, после установки вот этого списка кода перестает работать пагинация:
Последнюю строку нужно заменить на такую:
Спасибо как проверю отпишусь ))
Все супер! Работает! Спасибо выручил как всегда!
Спасибо за отличное решение. Выводит все в нужном формате, но проблема – выводит одно и то же 4 раза! Подскажите, как от этого избавиться?
Не знаю. У меня ничего не дублируется. Скорее всего, что-то неправильно сделали.
Может, вот здесь что-то не так:
А ваше решение, как раз в content-work.php
Извините, что не по теме, но все-таки…
У меня почему-то не работает такая простая, казалось бы, штука: 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’);
}
Но по при увеличении количества дочерних рубрик это перестанет быть удобным. Подскажите, что не так? Как правильно прописать код?
Кстати, очень удобный вывод новостей. Но при большом количестве категорий становится неудобно.
Дмитрий, добрый день!
Прочитав вашу статью в принципе все понятно, но когда я вставляю ваш код в index.php ничего не меняется.
Код index.php
Огромная просьба подскажите пожалуйста в какое место нужно вставить Ваш код или как его преобразовать, чтобы вывести 4 блока (4 рубрики) на галвной.
Заранее спасибо!
Вставьте вместо кода
<div class="pad group">...</div><!--/.pad-->
.Если у вас в шаблоне есть файл home.php, тогда вставлять нужно в него, а не в index.php.
Спасибо за ответ, но когда, вставляю вместо блока на который Вы указали, не выводиться вообще ничего, подозреваю что в цикле который нужно заменить определен еще вывод самих статей (возможно вот это echo ”)
а по другому вывести нельзя или же надо прописать что то в стилях.
Если подскажете в каком хоть направлении думать буду очень благодарен.
Мне больше нечего посоветовать.
Привет, твой код отлично работает для стандартной таксономии category.
А если мне нужно делать почти тоже самое только из своей таксономии ?
С таксономиями вообще не дружу.
Интересно.
А нет у вас статейки как в 3-х блоках вывести 3 отдельные рубрики?
Отличная статья, и отлично закомментированный код. Его просто и понятно читать. Респект автору за четкую работу – таких мало. Все четко и работает как нужно. Короч я такое давно хотел сам сделать – только руки не доходили. СПАСИБО!
Привет, спасибо за отличный код. Работает на ура. Как то пытался такой написать только подходил с другой стороны – вначале находил рубрики, все работало так же, за исключением того что обновленная рубрика не двигалась на первое место. А это не удобно.
Есть вопрос кстати. Сайт как известно должен быть красивым, а у меня публикуется примерно 1-2 к статей в день. И порой с одной рубрики а порой с разных. В итоге блок статей может быть просто разной длины. Тут не угадать. Я закрыл вопрос тем, что с помощью CSS скрыл все блоки после 17 го – то есть показываю только 17 новых статей из разных рубрик. Т е в каждой рубрике по одной статье. А как сделать такое без CSS, просто выводить 17 результатов ПОСЛЕ всех фильтров. Заранее спасибо!