Как вывести рубрики в таком виде

Требуется организовать на Главной вывод рубрик с несколькими постами из каждой рубрики.
Вот пример – http://i079.radikal.ru/1101/c8/23c1ff7d8899.jpg

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

Реально ли вообще это сделать на wordpress без использования множественных циклов?

И как такое можно сделать?

Множественный цикл без использования множественного цикла сделать не реально 🙂

Проведите "вскрытие" нескольких т.н. журнальных Тем и посмотрите, как там сделан вывод. Если не обращать внимание на особенности управления из админки и на специфику оформления, там везде одно и то же: несколько идущих подряд query_posts(‘cat=N’) + Цикл.

А если рубрик 10 или 20?
Получится 20 или 40 циклов – это же ужас что такое!

40 рубрик на морде – действительно, ужас. Для посетителя 🙂 10 – нормально. Но лучше 7. Сделайте правильную двух- (или более) уровневую рубрикацию, выводите на морду только верхний уровень – и всё будет в рамках приличия.

Пока у меня получается использовать два цикла
– для вывода названия рубрики и
– списка постов из нее.

Если вывести на морду 7 рубрик, значит будет 14 циклов.

          <?php $recent = new WP_Query("cat=1&showposts=1"); while($recent->have_posts()) : $recent->the_post();?>
              <h2><?php the_category(', ') ?></h2>
          <?php endwhile; ?>
          <ul>
          <?php global $post;
             $myposts = get_posts('showposts=10&cat=1');
             foreach($myposts as $post) : setup_postdata($post);
          ?>             
                <li><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title(); ?>"><?php the_title() ?></a></li>
             
          <?php endforeach; ?>
          </ul>

Ю.Б., подскажите, пожалуйста, как обойтись для этого одним циклом?

Почему 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();

ЗЫ Никаких гарантий 🙂

У меня до основного цикла идет один сайдбар:

get_header();
$saved_posts = $posts;
get_sidebars(1);
$posts = $saved_posts;
rewind_posts();
if (have_posts()) : while (have_posts()) : the_post();
...

К сожалению не сработало – выдает ошибку в 3й строке.

Ну это же набросок, эскиз, структурная схема, если хотите. Его нужно правильно срастить с Вашим кодом. Я бы дал точный код, но я отсюда плохо вижу, что у Вас в шаблоне – мартышка к старости слаба глазами стала 😀

Я бы дал точный код, но я отсюда плохо вижу, что у Вас в шаблоне

Юрий Дмитриевич, вы всегда знаете ответ на все наши вопросы, поэтому нам уже кажется, что вы и с форума все видите 🙂

Вот структура файла single.php:

<?php get_header(); ?> 

 <div id="page">  
      
            <?php include(TEMPLATEPATH. "/sidebar_1.php"); ?>
         
            <div class="maincolumn">
                <?php include(TEMPLATEPATH. "/includes/single1.php"); ?>
            </div><!-- end  main -->
            
            <?php include(TEMPLATEPATH. "/sidebar_2.php"); ?>

            <?php include(TEMPLATEPATH. "/sidebar_3.php"); ?>

</div><!-- end page -->  
    
<?php get_footer(); ?>

Типа так

<?php get_header();  $saved_posts = $posts; ?> 

 <div id="page">  
      
            <?php include(TEMPLATEPATH. "/sidebar_1.php"); ?>
         
            <div class="maincolumn">
                <?php $posts = $saved_posts;
                          rewind_posts();
                          include(TEMPLATEPATH. "/includes/single1.php"); ?>
            </div><!-- end  main -->
            
            <?php include(TEMPLATEPATH. "/sidebar_2.php"); ?>

            <?php include(TEMPLATEPATH. "/sidebar_3.php"); ?>

</div><!-- end page -->  
    
<?php get_footer(); ?>

Не сработало, увы…

<?php get_header();  $saved_query_string = $query_string; ?> 

 <div id="page">  
      
            <?php include(TEMPLATEPATH. "/sidebar_1.php"); ?>
         
            <div class="maincolumn">
                <?php query_posts($saved_query_string);
                          include(TEMPLATEPATH. "/includes/single1.php"); ?>
            </div><!-- end  main -->
            
            <?php include(TEMPLATEPATH. "/sidebar_2.php"); ?>

            <?php include(TEMPLATEPATH. "/sidebar_3.php"); ?>

</div><!-- end page -->  
    
<?php get_footer(); ?>

Ура!!! Получилось.
Спасибо.

Anonymous
Отправить
Ответ на: