Функция вывода всех постов по месяцам написания
Надеюсь, я вам еще не надоел своими функциями.
В этом посте я поведу очередное повествование о функции вывода в WordPress, правда, на этот раз функция совсем даже не моя, а автора темы Blix Theme, функция переросла из темы в плагин, стараниями автора блога rmarsh.com, который выдрал вышеупомянутую из темы и сделал плагин с названием «Blix Archive».
Как Dimox нашел этот плагин, я не имею ни малейшего понятия, Дима – золотоискатель «Причем здесь Dimox» - спросите вы? «Как причем?» - отвечу я. Ведь именно он, когда-то давно, дал мне ссылку на этот плагин, после того как я, будучи зеленым ковырятелем WordPress обратился к «гуру в веб-разработке» Dimox’у, показать код его карты сайта. Кстати, кто не знаком с Димой и его отличным блогом срочно знакомимся.
После того, как Дима услужливо направил меня по ссылке, где я скачал плагин я вернул все на места своя – похоронил плагин, предварительно вытащив из него функцию вывода, которой сейчас с вами и поделюсь.
Такова история нижеприведенной функции и этого поста
Ну, а теперь к делу.
Функция, которую я собираюсь представить, выводит посты, группируя их по месяцу написания, и выглядит это как-то так:

А сама функция выглядит именно так:
/* Функция вывода постов по месяцу. ---------- * Параметры: * $show_comment_count(0) - показывать ли колличество комментариев. 1 - показывать. * $before ('<h4>') - HTML тег до заголовка (названия месяца). * $after ('</h4>') - HTML тег после заголовка. * $year (0) - огриничить вывод годом. Если указать 2009, будут выведены записи за 2009 год по месяцам * $post_type ('post') - тип поста. Если нужно вывести нестандартный тип постов (отличный от post) * $limit(100) - ограничение количества выводиммых постов для каждого месяца. При большой базе, создается сильная нагрузка. Укажите 0 если нужно снять ограничение ---------- Пример вызова: <php echo get_blix_archive(1, '<h4>', '</h4>'); ?> */ function get_blix_archive( $show_comment_count=0, $before='<h4>', $after='</h4>', $year=0, $post_type='post', $limit=100 ){ global $month, $wpdb; $result = ''; $AND_year = $year ? $wpdb->prepare(" AND YEAR(post_date) = %s", $year) : ''; $LIMIT = $limit ? $wpdb->prepare(" LIMIT %d", $limit) : ''; $arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month, count(ID) as posts FROM " . $wpdb->posts . " WHERE post_type='$post_type' $AND_year AND post_status='publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC"); if( $arcresults ){ foreach( $arcresults as $arcresult ){ $url = get_month_link( $arcresult->year, $arcresult->month ); $text = sprintf('%s %d', $month[zeroise($arcresult->month,2)], $arcresult->year); $result .= get_archives_link($url, $text, '', $before, $after); $thismonth = zeroise( $arcresult->month, 2 ); $thisyear = $arcresult->year; $arcresults2 = $wpdb->get_results("SELECT ID, post_date, post_title, comment_status, guid, comment_count FROM " . $wpdb->posts . " WHERE post_date LIKE '$thisyear-$thismonth-%' AND post_status='publish' AND post_type='$post_type' AND post_password='' ORDER BY post_date DESC $LIMIT"); if( $arcresults2 ){ $result .= "<ul class=\"postspermonth\">\n"; foreach( $arcresults2 as $arcresult2 ){ if( $arcresult2->post_date != '0000-00-00 00:00:00' ){ $url = get_permalink($arcresult2->ID); //$arcresult2->guid; $arc_title = $arcresult2->post_title; if( $arc_title ) $text = strip_tags($arc_title); else $text = $arcresult2->ID; $result .= "<li>". get_archives_link($url, $text, ''); if( $show_comment_count ){ $cc = $arcresult2->comment_count; if( $arcresult2->comment_status == "open" OR $comments_count > 0) $result .= " ($cc)"; } $result .= "</li>\n"; } } $result .= "</ul>\n"; } } } return $result; }
Код этот нужно вставлять в файл темы function.php или непосредственно в файл, где эта функция используется (с ней я обычно так и поступаю), а там где мы хотим вывести список, вставляем такой код:
<?php echo get_blix_archive(1, '<h4>', '</h4>'); ?>
Чтобы настроить внешний вид списков, используйте CSS селекторы .postspermonth{...} и .postspermonth li{...}
Расширенное использование
В процессе эволюции функция претерпела ряд изменений и теперь, моими стараниями, умеет:
Ограничивать вывод годом
<?php echo get_blix_archive(1, '<h4>', '</h4>', 2009); ?>
Будут выведены посты только за 2009 год.
Понимать какой тип записей выводить
Можно выводить посты по месяцу, с указанием какой тип постов мы хотим вывести. Нужно это, если на сайте зарегистрирован новый тип записей, отличный от post
. Допустим новый тип записей называется post_type
, тогда код будет такой:
<?php echo get_blix_archive(1, '<h4>', '</h4>', 0, 'post_type'); ?>
Лимитировать вывод
И последний параметр передаваемый функции - это ограничитель (лимит) количества постов выводимых для каждого месяца. Его я добавил потому что при проверке этой функции на сайте с 20 тысячами постов безлимитный вывод сильно грузил процессор. По умолчанию для каждого месяца будет выводиться максимум 100 записей.
Эта функция безумно полезна. Это как вторая карта сайта, только по датам.
Как вставлять ее в тело статичных страниц тем, у кого нет плагина, который отрабатывает в посте или странице содержимое файла с любым кодом, например php или html?
Здравствуйте! А как насчет нагрузки базы данных несколькими сотнями запросами? Это не убьет сервер?
Смотря какие запросы и какой сервер.
Не совсем понятно, к чему этот вопрос здесь?
Вопрос этот к тому, что для построения такой карты в базу идут запросы. Сто постов - сто запросов. Тысяча постов - тысяча запросов и т.д.
Ожидал что так и ответите
С чего вы это взяли?
Код сначала собирает все месяца, в хронологическом порядке, а затем для каждого месяца делает отдельный запрос, чтобы получить записи за месяц. А значит 12 месяцев - 13 запросов, 24 месяца - 25 запросов, а постов в этих 12-ти/24-х месяцах может быть и 1000, и 10000.
Насколько этот код может убить сервер, судить не буду, но вроде терпимо, если использовать этот код на отдельной странице.
Провел практический тест. Сколько постов, столько же и запросов...
Вам тогда наверное стоит обратить внимание на то как работает стандартный кэш WordPress у вас на блоге. Утверждая свою позицию, вы ошибаетесь (я это на основе анализа кода говорю и практики)! Возможно функция get_permalink, которая должна работать на основе кэша, работает как-то по-другому и обращается к БД за данными
.
Для примера, в моей карте сайта стоит эта функция и внизу страницы показаны запросы, как видите там их 18, когда на любой другой статической странице их 11.
Очень полезная функция! А есть возможность выводить записи по месяцам только из определенной категории? уже долго бьюсь с этой задачей
Да такое вроде можно сделать. Но придется попотеть над изменением запроса к БД. Сорри я помочь не могу.
Подскажите пожалуйста, а как в wordpress выделить старые записи? Тоесть, чтобы, например, если запись старше 30 дней, то к дате публикации автоматически добавлялась пометка "архив" или "устарело"?
Спасибо.
в functions.php вставляем
использование
Супер! Спасибо за функцию!
Подскажите, это мне так везет или все из-за локального сервера?
Сначала, функция вывода последних записей так отображались а теперь функция вывода архива.
Вставил функцию вывел где нужно, а в итоге:
Так не должно быть, поправил код, обнови...
Обновил код, все работает спасибо.
Спасибо за превосходные функции, не люблю плагинами перегружать сайт.