Требуется организовать на Главной вывод рубрик с несколькими постами из каждой рубрики.
Вот пример – http://i079.radikal.ru/1101/c8/23c1ff7d8899.jpg
Сначала собиралась переделать для этого какой-нибудь плагин карты сайта, но то, что получилось, работает криво.
Реально ли вообще это сделать на wordpress без использования множественных циклов?
И как такое можно сделать?
Множественный цикл без использования множественного цикла сделать не реально 🙂
Проведите "вскрытие" нескольких т.н. журнальных Тем и посмотрите, как там сделан вывод. Если не обращать внимание на особенности управления из админки и на специфику оформления, там везде одно и то же: несколько идущих подряд query_posts(‘cat=N’) + Цикл.
А если рубрик 10 или 20?
Получится 20 или 40 циклов – это же ужас что такое!
40 рубрик на морде – действительно, ужас. Для посетителя 🙂 10 – нормально. Но лучше 7. Сделайте правильную двух- (или более) уровневую рубрикацию, выводите на морду только верхний уровень – и всё будет в рамках приличия.
Пока у меня получается использовать два цикла
– для вывода названия рубрики и
– списка постов из нее.
Если вывести на морду 7 рубрик, значит будет 14 циклов.
Ю.Б., подскажите, пожалуйста, как обойтись для этого одним циклом?
Почему 14? Для каждой рубрики используется один Цикл.
У меня на times.kharkov.ua сделано приблизительно так (кое-какие фишки вычеркнул:))
$cats = get_categories(‘include=18,26,28,46,56,13’);
foreach ($cats as $category) {
print ‘<h2>’.$category->name.'</h2>’;
query_posts(array(‘cat’ => $category->cat_ID,’showposts’=>4, ‘post__not_in’ => $showed_ids));
while (have_posts()) {
the_post();
$showed_ids[] = get_the_ID();
print ‘<h3><a href="’.get_permalink().’">’.get_the_title().'</a></h3>’;
}
}
Ю.Б., спасибо.
Это то, что нужно.
Вот попыталась немного модифицировать ваш код под свои задачи, а он перестал работать – выводит только один анонс.
[code-
<?php $cats = get_categories(‘include=’.get_theme_mod(‘block1′).’&exclude=’.get_theme_mod(‘video’).”);
foreach ($cats as $category) {
print ‘<h2>’.$category->name.'</h2>’;
query_posts(array(‘cat’ => $category->cat_ID,’showposts’=>10, ‘post__not_in’ => $showed_ids));
while (have_posts()) { the_post();
$showed_ids
= get_the_ID();
?>
<div class="block1">
<?php $image = get_post_meta($post->ID, ‘thumbnail’, $single = true);
if($image !== ”) { ?>
<a href="<?php the_permalink() ?>" rel="bookmark" >
<img src="<?php echo get_option(‘home’); ?><?php $values = get_post_custom_values("thumbnail"); echo $values[0]; ?>" alt="<?php the_title(); ?>" class="left" width="72" height="44" />
</a>
<?php } ?>
<div class="tright">
<?php the_content_limit(110); ?>
<a class="arrow" href="<?php the_permalink(); ?>"></a>
</div>
</div>
<?php
}
}
?>[/code]
В чем я ошиблась?
Вроде всё нормально. Я бы проверил, какие рубрики попадают в список. Поставьте после
$cats = get_categories(‘include=’.get_theme_mod(‘block1′).’&exclude=’.get_theme_mod(‘video’).”);
отладочный вывод
print_r($cats);
Если всё правильно, то проверил бы выбранные посты
после query_posts()
print_r($posts);
Странная вещь обнаружилась – если поставить несколько подобных циклов друг после друга
(а мне именно так и нужно для того, чтобы каждый из них выводил записи из определенной рубрики),
то работает только первый цикл.
Остальные выводят только названия рубрик.
В чем тут может быть засада?
Так всё-таки, что возвращает get_categories(‘include=’.get_theme_mod(‘block1′).’&exclude=’.get_theme_mod(‘video’).”); ?
Подозреваю, что только одну рубрику. В моем примере get_categories(‘include=18,26,28,46,56,13’); дает массив из шести рубрик, подлежащих выводу на главной.
Мне нужно два варианта вывода рубрик на Главной:
– блок рубрик (10 рубрик) – с этим ваш код прекрасно справился.
– несколько блоков, в которых выводится по 10 записей из отдельных рубрик.
Я пыталась приспособить ваш код и для этих целей тоже, чтобы заменить используемый мной вариант из 2х циклов – но тут не получается.
Array ( [0] => stdClass Object ( [term_id] => 22 [name] => Проишествия [slug] => proishestviya [term_group] => 0 [term_order] => 0 [term_icon] => http://test1.ru/wp-content/plugins/category-page-icons/img/shared-pictures-16×16.png [term_taxonomy_id] => 22 [taxonomy] => category [description] => [parent] => 11 [count] => 7 [cat_ID] => 22 [category_count] => 7 [category_description] => [cat_name] => Проишествия [category_nicename] => proishestviya [category_parent] => 11 ) )
Ну так для "одиночных" блоков не надо никаких хитростей, обычный Цикл
query_posts(‘cat=22&showposts=10’);
while (have_posts()) {
the_post();
….
}
и так несколько раз, меняя 22 на другое число.
У меня в 1м цикле выводится название категории,
а во 2м – 10 названий постов.
Такой вывод пользователю очень удобно настраивать – он выбирает в админке категорию из выпадающего списка и она сразу же отображается на странице в виде Названия категории и Списка постов из нее.
Минус здесь только один – приходится использовать два цикла, а хотелось, чтобы был один.
Но это у меня никак не выходит.
P.S. Если использовать обычный цикл, то название категории выводится 10 раз – по одному разу с каждым названием поста из этой категории.
Хоть убей, не понимаю, зачем Цикл для вывода имени категории?
$category = get_category(22);
print $category->name;
В том то и проблема, что работает только одиночный цикл, а если поставить несколько подобных циклов друг после друга,
[code- <?php $cats = get_categories(‘include=22’);
foreach ($cats as $category) {
print ‘<h2>’.$category->name.'</h2>’;
print ‘<ul>’;
query_posts(array(‘cat’ => $category->cat_ID,’showposts’=>7, ‘post__not_in’ => $showed_ids));
while (have_posts()) {
the_post();
$showed_ids
= get_the_ID();
print ‘<li><a href="’.get_permalink().’">’.get_the_title().'</a></li>’;
}
}
?>
</ul>[/code]
то работает только первый цикл.
Остальные выводят только названия рубрик.
Может, все посты уже выведены в предыдущих блоках? Тогда уберите предотвращение дублирования ‘post__not_in’ => $showed_ids
ВОТ! Это оно и было.
Спасибо ОГРОМНОЕ!
Остался последний вопрос, какой параметр функции get_categories запрещает вывод подкатегориий?
Я пыталась манипулировать параметрами child_of, parent и pad_counts , но что-то не получается избавиться от детских категорий.
<?php $cats = get_categories(‘?”);
Так вроде ж get_categories с параметром include и так возвращает только те категории, которые указаны в списке.
Юрий Дмитриевич, я пытаюсь вывести все существующие родительские категории, чтобы не указывать их вручную.
То есть, только первого уровня? Тогда попробуйте parent=0.
Спасибо.
Просто гора с плеч, все идеально работает.
Поздравляю! 🙂
По ходу возник еще один вопрос – как сделать название категории в этом цикле ссылкой на категорию?
print ‘<h2><a href="’.get_category_link($category->cat_ID).’">’.$category->name.'</a></h2>’;
Спасибо.
Ох, рано радовалась…
Перешла на страницу записей, а там выводится цикл из левого сайдбара.
И в архивах то же самое, и в рубриках.
Нашла в кодексе
рецепт для этого случая:
"Для того чтобы второй раз использовать цикл, с таким же запросом, вызовите функцию rewind_posts(). Она сбросит счетчик цикла и позволит вам выполнить другой цикл."
[code- <?php $cats = get_categories(‘include=’.get_theme_mod(‘block4’).”);
foreach ($cats as $category) {
print ‘<h2>’.$category->name.'</h2>’;
query_posts(array(‘cat’ => $category->cat_ID,’showposts’=>10));
while (have_posts()) { the_post();
$showed_ids
= get_the_ID();
?>
<div class="block4">
<?php $image = get_post_meta($post->ID, ‘thumbnail’, $single = true);
if($image !== ”) { ?>
<a href="<?php the_permalink() ?>" rel="bookmark" >
<img src="<?php echo get_option(‘home’); ?><?php $values = get_post_custom_values("thumbnail"); echo $values[0]; ?>" alt="<?php the_title(); ?>" class="left" width="107" height="65" />
</a>
<?php } ?>
<div class="tright">
<?php the_content_limit(110); ?>
<a class="arrow" href="<?php the_permalink(); ?>"></a>
</div>
</div>
<?php }} ?>
<?php rewind_posts(); ?>[/code]
Пыталась вызывать эту функцию после цикла в сайдбаре и перед следующим циклом в файле single.php – не работает.
Наверное это устаревшая функция.
Как теперь остановить этот цикл в сайдбаре, чтобы он не продолжался и в центральной колонке?
Подозреваю, что Вы не поняли, что делает rewind_posts(). Находящийся в Цикле the_post() при каждом вызове берет следующий пост из массива, выбранного в ините или запросом query_posts. Чтобы по второму разу пройтись по той же выборке и используется "перемотка на начало".
Неправильный вопрос 🙂 Дело не в Цикле, а в том, что выборка, сделанная в ините, перебита запросами query_posts(). Чтобы не было таких коллизий, сайдбары программно располагают после обработки основного контента. К тому же это положительно сказывается на семантике страницы (для HTML<5). При этом визуально сайдбар может находиться хоть перед хедером – спасибо CSS. Это, кстати, основной плюс divной верстки в борьбе с табличной, у которой порядок вывода строго совпадает с порядком отображения.
А по другому никак?
Не хочется переверстывать шаблон – уже почти закончила.
Шаблон 4-колоночный, переверстать его – большой гемор.
Можно попробовать в самом начале, до всех query_posts, сохранить массив $posts в другой переменной, а потом вернуть на место и, на всякий пожарный, перемотать. На крайний случай можно сохранить в начале $query_string, а потом скормить ее query_posts(). Но это лишний запрос к БД.
Я с этим самостоятельно не справлюсь.
Придется переверстывать. А так не хотелось…
Да чего там справляться-то?
get_header();
$saved_posts = $posts;
get_sidebars(1);
get_sidebars(2);
$posts = $saved_posts;
rewind_posts();
if (have_posts()) : while (have_posts()) : the_post();
…
endwhile; endif;
get_footer();
ЗЫ Никаких гарантий 🙂
У меня до основного цикла идет один сайдбар:
К сожалению не сработало – выдает ошибку в 3й строке.
Ну это же набросок, эскиз, структурная схема, если хотите. Его нужно правильно срастить с Вашим кодом. Я бы дал точный код, но я отсюда плохо вижу, что у Вас в шаблоне – мартышка к старости слаба глазами стала 😀
Юрий Дмитриевич, вы всегда знаете ответ на все наши вопросы, поэтому нам уже кажется, что вы и с форума все видите 🙂
Вот структура файла single.php:
Типа так
Не сработало, увы…
Ура!!! Получилось.
Спасибо.