Это продолжение поста о перелинковке статей.
В этой статье я хочу поделиться очередной функцией для WordPress, в задачи, которой входить вывод предыдущих записей из категории (рубрики), текущей статьи. Функция, так же, создает кольцевую перелинковку (см. первую статью).
Принципиальное отличие этой функции в том, что она выводит предыдущие записи из категории, тогда как, прошлая подобная функция выводит просто предыдущие записи.
Почти, такую же функцию я публиковал в комментариях на сайте Dimox.name здесь. Почему "почти"? Потому что, эта функция обладает рядом преимуществ над той, что была опубликована на Dimox.name, а именно:
- Можно задавать формат вывода, благодаря чему её очень просто внедрить в любой шаблон;
- Для этой функции не нужно заранее определять текущую категорию (функция сама определит её), т.е. меньше лишнего кода в шаблоне и проще новичкам.
- Функция не использует, немного грузовую, функцию самого WordPress get_posts()
- К каждому тегу ссылки добавляется классы li1 и li2, чтобы легко можно было раскрасить список в зебру.
- Можно включить кеширование. Подробнее об этом ниже.
- Список сортируется по дате, а не по ID, т.е. если запись была опубликована задним числом она будет выводится как нужно.
Использование функции
А вот, собственно, и код, который нужно поместить в ваш файл шаблона functions.php.
/** Предыдущие записи из рубрики (относительно текущей записи) + кольцевая перелинковка
----------------------------------------------------------------------------------------
Параметры передаваемые функции. В скобках указано дефолтное значение.
post_num (5) = количество ссылок
format ('') = {date:j.M.Y} - {a}{title}{/a} ({comments})
cache ('') = включить кеш (по умолчанию выключен). Пишем 1, чтобы включить
list_tag (li) = Тег списка.
echo (true) = Выводить на экран или возвращать для обработки (false)
*/
function kama_previous_posts_from_cat ($post_num=5, $format = '', $cache = '', $list_tag='li', $echo=true){
global $post, $wpdb;
$cache_key = (string) md5( __FUNCTION__ . $post->ID );
$cache_flag = __FUNCTION__;
if ( $cache && $cache_out = wp_cache_get($cache_key, $cache_flag) ){
if ($echo) return print($cache_out);
else return $cache_out;
}
$cat = get_the_category($post->ID);
$cat_id = (int) $cat[0]->term_id;
$same_join = "SELECT ID, post_title, post_date, comment_count, guid
FROM $wpdb->posts p
LEFT JOIN $wpdb->term_relationships rel ON (p.ID = rel.object_id)
LEFT JOIN $wpdb->term_taxonomy tax ON (rel.term_taxonomy_id = tax.term_taxonomy_id)";
$same_and = "AND tax.term_id = '$cat_id'
AND tax.taxonomy = 'category'
AND p.post_status = 'publish'
AND p.post_type = 'post'";
// пробуем получить предыдущие записи
$sql = "$same_join
WHERE p.ID < {$post->ID}
$same_and
ORDER BY p.post_date DESC
LIMIT $post_num";
$res = $wpdb->get_results($sql);
$count_res = count($res);
// если количество меньше нужного, делаем 2-й запрос
if ( !$res || $count_res<$post_num ){
$exclude = $post->ID;
if ($res) foreach ($res as $id) $exclude .= ','.$id->ID;
$post_num = (int) $post_num-$count_res;
$sql = "$same_join
WHERE p.ID NOT IN ($exclude)
AND p.ID != {$post->ID}
$same_and
ORDER BY p.post_date DESC
LIMIT $post_num";
$res2 = $wpdb->get_results($sql);
$res = array_merge($res,$res2);
}
if (!$res) return false;
if ($format) preg_match ('!\{date:(.*?)\}!',$format,$date_m);
foreach ($res as $pst){
$x == 'li1' ? $x = 'li2' : $x = 'li1';
$Title = $pst->post_title;
$a1 = "<a href='". get_permalink($pst->ID) ."' title='{$Title}'>";
$a2 = "</a>";
if ($format){
$date = apply_filters('the_time', mysql2date($date_m[1],$pst->post_date));
$Sformat = str_replace ($date_m[0], $date, $format);
$Sformat = str_replace('{title}', $Title, $Sformat);
$Sformat = str_replace('{a}', $a1, $Sformat);
$Sformat = str_replace('{/a}', $a2, $Sformat);
$Sformat = str_replace('{comments}', (($pst->comment_count==0)?'':$pst->comment_count), $Sformat);
}
else $Sformat = $a1.$Title.$a2;
$out .= "\n<$list_tag class='$x'>{$Sformat}</$list_tag>";
}
if ($cache) wp_cache_add($cache_key, $out, $cache_flag);
if ($echo) echo $out;
else return $out;
}
После того, как код, успешно, скопирован в файл темы functions.php, в том месте где мы хотим вывести предыдущие записи из текущей категории вызываем функцию так:
<ul> <?php kama_previous_posts_from_cat (5); ?> </ul> // 5 это количество выводимых ссылок
Вот, собственно, и все, что нужно сделать для простого использования функции.
Важно! Вызов будет работать корректно только в файле темы, отвечающем за вывод постов (обычно это single.php).
Расширенное использование
Для настройки формата вывода исползуйте:
- {comments} - покажет колличество комментариев у статьи;
- {title} - заголовок статьи;
- {date:j.M.Y} - дата в формате j.M.Y (11.Апр.2010);
- {a} и {/a} - тег ссылки. Открывается и закрывается.
Вызов будет таким:
<ul>
<?php kama_previous_posts_from_cat (5, '{a}{title}{/a} ← {date:j.M.Y} // {comments}'); ?>
</ul>
// выведет список в формате - <li class='li1'><a href='http://ссылка' title='Заголовок статьи'>Заголовок статьи</a> ← дата // колличество комментариев</li>
Использование кеша
Так как, в WordPress кеш, начиная с 2.х версии (не помню точно), выключен, то кеширование будет работает только в связке с плагинами кеширования, которые совместимы с классом WP_Object_Cache. В частности, я говорю про плагины Владимира: WP File Cache и SJ Object Cache.
Если вы используете плагины постраничного кеширования или вообще не используете плагины кеширования, то включать кеш у этой функции смысла нет.
Вызов функции с использованием кеша
<ul> <?php kama_previous_posts_from_cat (5, '', 1); ?> </ul> // выведет 5 ссылок и закеширует результат в файл, с последующим извлечением информации из этого файла. Файл будет создавать отдельный для каждого поста.
Тег списка
Можно изменить тег списка li на любой другой, например div
<?php kama_previous_posts_from_cat (5, '', 0, 'div'); ?> // выведет 5 ссылок в формате - <div class='li1'><a href='http://ссылка' title='Заголовок статьи'>Заголовок статьи</a></div> .
И последнее
Если передать последний (5-й) параметр, как false, то результат будет возвращен для обработки (return), а не выведен на экран.
- Предыдущие по меткам
- Предыдущие записи
- Перелинковка статей (предыдущие записи) ← 19.Апр.2010 // 11
- Плагин опроса для WordPress - Democracy Poll ← 12 июня 2010 // 23
- Плагин для легкого управления сайтом на WordPress ← 23 апреля 2010 // 18
- Считаем количество посещений страниц на WordPress без плагинов ← 21 апреля 2010 // 25
Спасибо, работает, но появился один баг. Если зайти в рубрику вот так "domain.ru/rubrika" то все нормально, а если в конце слеш поставить "domain.ru/rubrika/" то ошибка:
Warning: Cannot modify header information - headers already sent by (output started at /var/www/user/data/www/domain.ru/wp-content/themes/tema/functions.php:119) in /var/www/user/data/www/domain.ru/wp-includes/pluggable.php on line 868
И еще на странице авторизации:
Warning: Cannot modify header information - headers already sent by (output started at /var/www/user/data/www/domain.ru/wp-content/themes/tema/functions.php:119) in /var/www/user/data/www/domain.ru/wp-login.php on line 302
Warning: Cannot modify header information - headers already sent by (output started at /var/www/user/data/www/domain.ru/wp-content/themes/tema/functions.php:119) in /var/www/user/data/www/domain.ru/wp-login.php on line 314
Это проблема файла functions.php, а не проблема функции. Удалите
?>в вашем functions.php в самом конце. Если не поможет, покажите файл, я подскажу что не так, там проблема в неправильной разметке.Кстати, функцию нужно вставлять без начальной строчки
<?phpи конечной?>. Скорее всего проблема в этом. Поправил пост - убрал эти строчки.Ок, заработало, спасибо. Я уже надоел наверное, но 1 последний вопросец. Зачем в functions.php указано post_num=5, если кол-во ссылок указывается в
<ul> <?php kama_previous_posts_from_cat (5); ?> </ul>Если вам нужно 5, то можете ничего не указывать (
kama_previous_posts_from_cat();). Т.е. 5 это по умолчанию.Здравствуйте, все сделал как вы сказали спасибо, вроде работает, но вот например я зашел на страницу та вышло 5 ссылок потом ее перегрузил вышла одна и вот так они меняются все время. они не должны оставаться постоянными? или я что-то не так понял?
Должны быть постоянными, для каждой новости свои, т.е. на странице новости ссылки меняться не должны. Если у вас при обновлении страницы чет меняется, то вы что-то не то сделали, какой-то рандомный вывод настроили, а не эту функцию.
Я все сделал как вы и описали версия 3.0.1. все время меняется и берет из разных категорий.
Проверил на 3.0.1, все пашет на ура. Вы что-то не так делаете!
Если проблема не решится, киньте шаблон на t.kamaev@ya.ru
подтверждаю, хак рабочий и весьма неплохой.