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();
раз снежинкадва снежинкатри снежинкаа я четвертую сорву!отличная снежинка (голосов: 21)
UTW_ShowTagsForCurrentPost("commalist"); Ключевые темы: No Tags
show_post_count(); Просмотров: 20957

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;

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

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

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

  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;

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

  18. Татьяна Says:

    Здравствуйте. Делаю все, как вы сказали. Почему-то не работает permalink, title, подскажите!!!замучалась уже..
    1) $offset=$numpost*($paged-1);
    else $offset=0;
    $posts = get_posts(”numberposts=”.$numpost.”&category=1&offset=”.$offset);
    foreach($posts as $post) : start_wp();
    setup_postdata($post);
    ?>

    ” rel=”bookmark”>

    >’));?>

    –>

  19. Yantar Says:

    Татьяна, какая у вас версия вордпресс? И где (в каком шаблоне) вы это пишете?
    код можно заключать в тег <code>, чтобы он нормально отображался в комментах

  20. Мю Says:

    у меня такая странность..
    весь код этого блока получился такой:

    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);?>

    “>

    “>
    интересность опубликована:
    [Читать полностью/Комментировать]

    внутри все прекрасно отображается, но навигации нет.. она просто не показывается..(
    и правда - только тут нашла то, что нужно.. еще бы вывести её :)

  21. Мю Says:

    а.. прошу прощения.. с заменой кавычек код:


    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);?>

    ’>

    ’>
    интересность опубликована:
    [Читать полностью/Комментировать]

  22. Yantar Says:

    Мю, какая у Вас версия вордпресса? этот пост довольно старый, с новыми версиями есть свои тонкости.
    ну и напишите, что именно не выходит, что не получается?

  23. Мю Says:

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

    в итоге я сделала все через цикл while, потом долго не цеплялись комментарии, как-то я в итоге их прилепила)) и через второй по счету плагин удалось сделать их симпатичными)) page navi так и не сработал..

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

  24. Татьяна Says:

    Добрый день! У меня на сайте, в категориях выводятся последние записи, а не только записи принадлежащие к определенной категории. Не подскажите как сделать чтобы запись к категории, к примеру, “вентиляция”, выводилась только в ней и всё. И так у всех рубрик. Буду очень вам благодарна.

  25. Yantar Says:

    Татьяна, а у вас какая-то самодельная тема или скачанная? Если скачанная - дайте ссылку, я могу посмотреть, что там не так. Ну или сами посмотрите - есть ли у вас в папке темы файл category.php. Если нет, то надо смотреть на файл index.php, есть ли там слова типа query_posts. Ну и еще есть варианты.

  26. Алексей Просвет Says:

    Не получается у меня вывести нужное количество записей. Вставляю ваш код, пишет ошибку строки “else $offset=0;”
    Никак не могу разобраться, как с этим бороться. Помогите пожалуйста. Замучился уже искать проблему. Я новичок.

    ">

    “>

  27. Алексей Просвет Says:

    ">

    “>

  28. Алексей Просвет Says:

    Не работает почему-то тут тег

  29. Yantar Says:

    Алексей, выложите свой код куда-нибудь типа сюда http://pastebin.com/ и дайте ссылку. И напишите конкретно, чего вы хотите добиться.
    Эта запись была сделана в 2006 году, многое с тех пор могло измениться :)

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

show_manual_subscription_form();

Subscribe without commenting

endwhile;