single.php

include (TEMPLATEPATH . '/searchform.php');
if (have_posts()) : while (have_posts()) : the_post();
the_time('F j, Y'); апрель 26, 2006
the_author(); Yantar
the_category(', '); wordpress, для всех
the_ratings();
раз снежинкадва снежинкатри снежинкаа я четвертую сорву!отличная снежинка (голосов: 8)
UTW_ShowTagsForCurrentPost("commalist"); Ключевые темы: No Tags
show_post_count(); Просмотров: 9074

the_content();

Продолжаем разговор. ©
Цикл/The Loop - один из основных терминов в движке WordPress. Заглянешь в Кодекс по поводу любой wp-функции, и там обязательно будет стоять примечание: используется она внутри цикла или вне его.
Сам цикл нужен для того, чтобы вывести на главной странице или в на странице категории (или где еще угодно) несколько последних записей.

Стандартно он вызывается следующим способом:

if (have_posts()) : //проверка на наличие записей в принципе
while (have_posts()) : the_post(); //начинаем, собственно, цикл, перебор этих записей
название записи, анонс записи и прочие подробности
endwhile;//заканчиваем цикл
endif;//заканчиваем проверку

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

next_posts_link('« Назад');
previous_posts_link('Вперед »');


Вуаля, все готово к полноценному серфингу. Впрочем, весь этот код прописан в стандартной теме Кубрик, так что можно и не заморачиваться.

Однако, иногда такой вызов цикла не годится.
Вот, к примеру, я сейчас делаю сайт, где полно вложенных категорий и подкатегорий:

    Главная категория

      Дочерняя категория

      • Внук
      • Внучка
        • Правнучка
        • Правнук

И, допустим, у меня во внучатой категории полно записей, а в дочерней всего две или три. При этом мне необходимо, чтобы на странице дочерней категории были показаны анонсы только этой категории, а затем перечислялись имена имеющихся внуков, внучек и прочих потомков. Стандартный способ вызова цикла, описанный выше, не позволяет этого сделать. С его помощью можно разве что по-разному раскрасить анонсы записей: к примеру, записи принадлежащие именно дочерней категории выводить большими красными буквами, а записи потомков - маленькими и черными.
Если кому-то нужно - пожалуйста: достаточно внутри цикла прописать
if(in_category($cat)) {
выводим все красным болдом
}
else {
выводим по-человечески
}

К слову сказать, в переменной $cat содержится id текущей категории.
Если в этом условии прописать обычное игнорирование всех записей, которые не принадлежат к нужной категории, конечно, все сработает как надо. Только вот если у нас в опциях прописано выводить по 10 постов на страницу, а во внучатых категориях их 11, причем они появились там позже, чем в дочерней, то WP нам предъявит пустую страницу: он взял 10 последних постов, запустил цикл, проигнорировал все, что не удовлетворяло условиям и пошел отдыхать.

Как же вывести только те записи, которые относятся к нужной мне категории, и не выводить записи потомков? На помощь пришел второй способ:

$posts = get_posts('numberposts=10&category='.$cat);//пригодилась переменная $cat
foreach($posts as $post) : start_wp(); //начинаем цикл
setup_postdata($post);//эта строчка необходима, если кроме названия, даты и анонса нужно вывести еще какие-то подробности про запись, например, ее автора
название записи, автор записи, анонс записи
endforeach;//заканчиваем цикл

Теперь все хорошо, только вот функции next_posts_link(); и previous_posts_link(); отказываются работать. То есть, они работают: если у нас больше означенных 10 записей, появляется стрелка « с линком - и приводит нас на точно такую же страницу с теми же последними (а не предыдущими) 10 записями. Почему? Да потому у функции get_posts(); есть, оказывается, еще и параметр offset, по умолчанию равный 0. То есть, вызывая эту функцию мы говорим: дайте-ка последние 10 записей, начиная с 0.
Тут нам на помощь приходит впроброс упомянутая в Кодексе переменная $paged, которая сообщает, на какой странице категории мы сейчас находимся. Дальше все просто - пишем сначала:

$numpost=10;//сколько записей в обычной категории
if($paged>1) $offset=$numpost*($paged-1);
else $offset=0;//чтобы знать, с какой статьи начать, если это не первая страница категории

а потом, при вызове функции get_posts(); не забываем упомянуть, с какой записи мы начинаем отсчет:
$posts = get_posts('numberposts='.$numpost.'&category='.$cat.'&offset='.$offset);
foreach($posts as $post) : start_wp();
setup_postdata($post);
название записи, автор записи, анонс записи
endforeach;

Вот теперь у нас все как надо.

Насколько этот текст оказался полезным?
раз снежинкадва снежинкатри снежинкаа я четвертую сорву!отличная снежинка (голосов: 8)
comments_template();

Комментарии (17) к записи «Постраничный вывод записей в категории»

  1. Pepsimist Says:

    Посмотрел http://pogoda.vokrug.us/, ужасно понравились вложенные категории в сайдбаре, то есть как раз то, чего так не хватает. Для страниц в Wordpress можно задать родителя, но для записей нельзя. Как Вы умудрились так здорово сделать? Программирование для меня филькина грамота, поэтому, если можно, как-нибудь попроще, для дураков: какую строчку куда вставить, что где прописать и тд. Был бы ужасно благодарен хоть за какую-то помощь. Ссылки на кодекс wordpress бесполезны по причине незнания английского и программистского :)

  2. nachberlin Says:

    Как это нельзя? Все делается очень просто - в управлении категориями надо сначала создать родительскую, главную категорию. Потом создать еще одну, дочернюю (при создании в поле под названием можно выбрать родителя). И потом при написании поста надо просто помечать галочкой не родительскую, а дочернюю категорию.
    А чтобы в сайдбаре выводилась правильная иерархия категорий, надо просто прописать в функции wp_list_cats(’hierarchical=1&children=1′) - то есть даже эти параметры можно не прописывать, они по умолчанию, но если в теме прописано по-другому, то надо исправить. и остальные аргументы, если они есть, не трогать.

  3. Pepsimist Says:

    Да, здорово, спасибо! Не додумался попробовать и для записей сделать категории. Туплю.
    И, наверное, еще туплю, потому что записи из дочерней выводятся и в родительской тоже. А это совсем не нужно. Тоже, видимо, где-то что-то добавить надо, но пока в шаблонах ничего подходящего не нашел. Или руки кривые. Или голова кривая.

  4. nachberlin Says:

    ну вот именно в записи, которую мы сейчас комментируем, написано, как я именно с этой проблемой справилась :-)
    прочитайте ее внимательно - я рассказываю, как пользоваться функцией get_posts()

  5. Pepsimist Says:

    Да, вам хорошо, вы умные, а меня в детстве головой роняли. У меня мозговые клетки стукнутные.
    Вот не нашел я нигде этого get_posts() :(
    И куда $posts прописывать все равно не понял. И в каком шаблоне…
    Пожалели бы старого больного человека, ткнули бы изящным пальчиком, мол, это вот сюда, а это сюда. И было бы мне щастье.
    Нет, правда, все облазил, все перечитал аж под лупой, но ни фига не понял. Я ведь даже слово функция с фрикцией путаю, а php с рпр ;)
    А тоже ведь хочется, чтоб как у людей. Рюшечки там, вазончики, слоники на пианине.

  6. nachberlin Says:

    В шаблоне категорий это все надо прописывать.
    Там у Вас сейчас примерно такое идет наверняка:
    if (have_posts()) :
    while (have_posts()) : the_post();
    название записи, анонс записи и прочие подробности
    endwhile;
    endif;

    а надо вот так:
    $numpost=10;//сколько записей выводить в обычной категории, можете поменять число
    if($paged>1) $offset=$numpost*($paged-1);
    else $offset=0;
    $posts = get_posts(’numberposts=’.$numpost.’&category=’.$cat.’&offset=’.$offset);
    foreach($posts as $post) : start_wp();
    setup_postdata($post);
    название записи, автор записи, анонс записи
    endforeach;

    То есть, середину оставляете (название записи, автор записи, анонс записи), а начало и конец меняете.

  7. semul Says:

    а вы не подскажете, для какой версии вордпресс действует вышесказанное?
    это единтсвенное что я нашла в сети по теме, а применить никак не могу(

  8. nachberlin Says:

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

  9. PODZEMKA Says:

    Подскажите, а как можно отключить вывод новостей одной из категорий кроме как query_posts(`cat=-2`);

    как это делается в Loopе или есть еще какие нить варианты?

  10. Mixa Says:

    Все очень круто, но новичку не понять. Может вы будете смеяться, но япробовал вставить код ($posts = get_posts(’numberposts=10&category=’.$cat);/……….) прямо на странице - написано ведь: “… на странице категории (или где еще угодно)…”…
    У меня задание - вывести на станице, скажем, последние десять сообщений категории N, с возможностью просмотреть остальные сообщения данной категории.
    Можно усложнить задачу - на одной и то й же странице делается таблица, в первом столбце которой вывводится 10 последних постов категории Х, а в другом - то же самое, только категории Y.
    Как это сделать - ума не приложу…

  11. nachberlin Says:

    >>Можно усложнить задачу - на одной и то й же странице делается таблица, в первом столбце которой вывводится 10 последних постов категории Х, а в другом - то же самое, только категории Y.

    $posts = get_posts(’numberposts=10&category=x’);
    $posts = get_posts(’numberposts=10&category=y’);

    x и y - id категорий
    возможно, между двумя блоками понадобится вызов функции rewind_posts();

  12. nachberlin Says:

    а насчет новичку не понять - похоже и впрямь надо термины объяснять :-)

  13. Mixa Says:

    М-дя, похоже что ни в России, ни в Украине никто не знает как можно простым способом заставить выводить в нужном месте (на странице или в посте, а не во всем блоге, изменив че-то там в шаблонах) нужное кол-во заголовков постов с определенной категории…
    Все умничают, но на последний коммнетароий http://wordpress.org/support/topic/99618?replies=10#post-526752 никто не может ответить…

  14. Andrew Says:

    Чувааак! Респект! на 2.3.2 работает - проверено!

  15. Олег Says:

    Спасибо! У меня есть одна непонятка. Почему после использования query_posts переменная query_string сбрасывается на пустое значение?

  16. Cygnus Says:

    Для новичков как я, вот целый код:
    1) $offset=$numpost*($paged-1);
    else $offset=0;
    $posts = get_posts(’numberposts=’.$numpost.’&
    category=-4(Сюда ту категорию которую хотите исключить,если их несколько то пишутся через запятую)’.$cat.’&offset=’.$offset);
    foreach($posts as $post) : start_wp();
    setup_postdata($post);?>

    ” rel=”bookmark”>

  17. Евгений Says:

    Доброго Вам времени суток.
    Сделал как вы описали.

    Следующий код:

    и

    заменил соответственно на

    $numpost=10
    if($paged>1) $offset=$numpost*($paged-1);
    else $offset=0;
    $posts = get_posts(’numberposts=’.$numpost.’&category=’.$cat.’&offset=’.$offset);
    foreach($posts as $post) : start_wp();
    setup_postdata($post);

    и endforeach;

    Но записи дочерних категорий так и выводятся в вышестоящих. (((

Есть комментарии?

It sounds like SK2 has recently been updated on this blog. But not fully configured. You MUST visit Spam Karma's admin page at least once before letting it filter your comments (chaos may ensue otherwise).
show_manual_subscription_form();

Subscribe without commenting

endwhile;