Как разбить цикл на несколько столбцов

11

Если у меня есть цикл из запроса категории, например:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<ul>
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<li>.. </li><?php wp_reset_query(); ?>
<?php endwhile; ?>
</ul>

Как бы создать предложение if, которое разбивает список через определенный интервал и запускает новый. Например, в 10-м посте верните a </ul>и начните новый <ul>в 11.

Это неверно, но для иллюстрации моей цели:

<?php $count =0;
    while($count <=50){
        if ($count == 9){
            echo "<li><a href='<?php the_permalink(); ?>'>
                      <?php the_title(); ?></a></li></ul>";
            } 
        elseif ($count == 10){
        echo "<ul><li><a href='<?php the_permalink(); ?>'>
                          <?php the_title(); ?></a></li>";
        }
        else {
        echo "<li><a href='<?php the_permalink(); ?>'><?php the_title(); ?></a></li>";
        }

Как правильно включить эту логику в цикл?

Zac
источник
Я обновил свой ответ чем-то, что должно быть в целом простым в использовании и проверено.
Хакре,

Ответы:

21

Создать столбцы для вашего запроса и удобного отображения

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

Более простой подход, который пришёл мне в голову, заключался в том, чтобы расширить «цикл» столбцами и до сих пор пришел к этому решению:

Объект WP_Query_Columns « дополняет » любой стандартный запрос WP столбцами, которые можно легко повторить. Первый параметр - это переменная запроса, а второй параметр - количество элементов, отображаемых в столбце:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<?php foreach(new WP_Query_Columns($the_query, 10) as $column_count) : ?>
    <ul>
        <?php while ($column_count--) : $the_query->the_post(); ?>
        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
    </ul>
<?php endforeach; ?>

Чтобы использовать его, просто добавьте класс WP_Query_Columns из этого списка в файл theme.php .

Расширенное использование

Если вам нужен номер столбца, который вы отображаете в данный момент (например, для некоторых четных / нечетных классов CSS, вы также можете получить его из foreach:

<?php foreach(new WP_Query_Columns($the_query, 10) as $column => $column_count) : ?>

И общее количество столбцов также доступно:

<?php 
    $the_columns = new WP_Query_Columns($the_query, 10);
    foreach($the_columns as $column => $column_count) : 
?>
    <h2>Column <?php echo $column; ?>/<?php echo sizeof($the_columns); ?></h2>
    <ul>...

Пример двадцать десять

Я мог бы быстро взломать двадцать десять тем для теста и таким образом добавить заголовки над любым циклом. Он вставлен в loop.php, начало - код темы:

<?php /* If there are no posts to display, such as an empty archive page */ ?>
<?php if ( ! have_posts() ) : ?>
    <div id="post-0" class="post error404 not-found">
        <h1 class="entry-title"><?php _e( 'Not Found', 'twentyten' ); ?></h1>
        <div class="entry-content">
            <p><?php _e( 'Apologies, but no results were found for the requested archive. Perhaps searching will help find a related post.', 'twentyten' ); ?></p>
            <?php get_search_form(); ?>
        </div><!-- .entry-content -->
    </div><!-- #post-0 -->
<?php endif; ?>

<!-- WP_Query_Columns -->
<?php 
    ### Needs WP_Query_Columns --- see http://wordpress.stackexchange.com/q/9308/178
    $query_copy = clone $wp_query; // save to restore later
    foreach( new WP_Query_Columns($wp_query, 3) as $columns_index => $column_count ) : ?>
    <ul>
        <?php 
        while ( $column_count-- ) : the_post(); ?>
            <li><h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyten' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2></li>
        <?php endwhile; ?>
    </ul>       
<?php endforeach; ?>
<?php $wp_query = $query_copy;?>

<?php
    /* Start the Loop.
    ...

Для более длинного ответа:

(именно так я и подошел к вышеприведенному материалу, но лучше объясняет, как на самом деле решить проблему с помощью простых математических операций. Мое новое решение - перебирать что-то заранее вычисленное.)

Это зависит от того, сколько вам на самом деле нужно, чтобы решить проблему.

Например, если количество элементов в столбце равно одному, это очень просто:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>    
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<ul>
    <li>.. </li>
<ul>
<?php endwhile;  wp_reset_query(); ?>
</ul>

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

  • Сколько предметов в одном столбце?
  • Сколько всего товаров?
  • Есть ли новый столбец для запуска?
  • И есть ли столбец до конца?

Последний вопрос довольно интересен для вывода HTML, поскольку вы, вероятно, хотите заключить не только элементы, но и столбец с элементами HTML.

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

А иногда даже мы не можем даже ответить на каждый вопрос с самого начала. Например, общее количество элементов: существует ли какое-либо, несколько, точное число, которое совпадает с целым числом столбцов в целом?

Даже ответ Яна Фабри может работать в некоторых случаях (как в моем примере выше для сценария «один элемент на столбец»), вас может заинтересовать что-то, что работает для любого количества элементов, возвращаемых WP_Query.

Сначала по математике:

//
// arithmetical example:
//
# configuration:
$colSize = 20;  // number of items in a column
$itemsTotal = 50; // number of items (total)

# calculation:
$count = 0; // a zero-based counter variable
$isStartOfNewColum = 0 === ($count % $colSize); // modulo operation
$isEndOfColumn = ($count && $isStartOfNewColum) || $count === $itemsTotal; // encapsulation

Этот код не запускается, поэтому давайте поместим это в простой текстовый пример

//
// simple-text example:
//
$column = 0; // init a column counter
for($count=0; $count<= $itemsTotal; $count++) {
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // update column counter

    if ($isEndOfColumn) {
        printf("/End of Column: %d\n", $column-1);
    }

    if ($isStartOfNewColum) {
        printf("<start of Column: %d\n", $column);
    }

    printf(" * item %d\n", $count);
}
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    printf("/End of Column: %d\n", $column);
}

printf("Done. Total Number of Columns: %d.\n", $column);

Это на самом деле работает и уже выводит некоторые данные:

<start of Column: 1
 * item 0
 * item 1
 * item 2
 * item 3
...
 * item 17
 * item 18
 * item 19
/End of Column: 1
<start of Column: 2
 * item 20
 * item 21
 * item 22
...
 * item 37
 * item 38
 * item 39
/End of Column: 2
<start of Column: 3
 * item 40
 * item 41
 * item 42
...
 * item 48
 * item 49
 * item 50
/End of Column: 3
Done. Total Number of Columns: 3.

Это уже очень хорошо имитирует, как это может выглядеть в шаблоне WordPress:

//
// wordpress example:
//
$count = 0; // init item counter
$column = 0; // init column counter
$colSize = 10; // column size of ten this time
$the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');
$itemsTotal = $the_query->post_count;
?>
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<?php
    # columns display variables 
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // update column counter

    if ($isEndOfColumn) {
        print('</ul>');
    }

    if ($isStartOfNewColum) {
        printf('<ul class="col-%d">', $column);
    }
?>
    <li> ... make your day ...
    </li>
<?php endwhile; ?>
<?php
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    print('</ul>');
}
// You don't have to do this in every loop, just once at the end should be enough
wp_reset_query();
?>

(Я не выполнил последний пример в среде WP, но он должен быть по крайней мере синтаксически правильным.)

hakre
источник
2

Это более общий вопрос программирования, но вот основная идея:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<ul>
<?php
$post_counter = 0;
while ($the_query->have_posts()) :
    $the_query->the_post();
    $post_counter++;
?>
    <li>.. </li>
<?php
    if ( 0 == $post_counter % 10 ) {
        echo '</ul><ul>';
    }
endwhile;
?>
</ul>
<?php
// You don't have to do this in every loop, just once at the end should be enough
wp_reset_query();
?>
Ян Фабри
источник
Операция по модулю - это в основном математический ответ. Но вашему примеру не хватает семантического вывода HTML. Я предложил нечто подобное в своем ответе, как вы можете себе представить, это заняло еще немного времени;)
Хакре,
wp_reset_query();не связано с переменной $ the_query. Это не нужно вообще, верно?
Хакре
@hakre: $the_query->the_post()перезапишет глобальную $postпеременную и wp_reset_query()восстановит ее (вызывая wp_reset_postdata()- чего может быть достаточно само по себе?).
Ян Фабри
Хорошо, я как-то смешал wp_query и немного опубликовал, думал, что это что-то сделает, $wp_queryно $the_queryбыл использован в примере. Однако я ошибся, добавлю его ко второму ответу для полноты.
Хакре
Вы не учитываете последний элемент. Если цикл заканчивается на число, кратное 10, вы получите пустой набор <ul></ul>.
Дэн Гейл
1

Там нет необходимости создавать отдельный вар для подсчета, так как вар запроса уже пересчитывает по адресу: $wp_query->current_post. Кроме того, вам необходимо учесть окончательную запись в списке, чтобы у вас не было пустых <ul></ul>в разметке.

<?php 
$the_query = new WP_Query('showposts=21&orderby=title&order=asc'); 
echo "<ul>";
while ($the_query->have_posts()) :
    $the_query->the_post();
    echo "<li>{$the_query->current_post}</li>";

    // Note that the post is already counted in the $the_query->current_post variable when in the loop. Add one to translate array counting to real counts.
    // Jan's example didn't account for the final entry in the list. Don't want empty <ul>'s hanging around
    if ((($the_query->current_post+1) % 10 == 0) && ($the_query->current_post+1 !== count($the_query->posts))):
        echo "</ul><ul>";
    endif;
endwhile;
echo "</ul>";
?>
Дэн Гейл
источник
Отметил. Пример добавлен.
Дэн Гейл
Круто, мне нравится это дополнение, потому что пустое <ul> </ ul> `предназначено только для 0 постов (но для тех, кто все еще есть) - но из того, что я узнал сегодня, эта форма самая маленькая с o введение новой функции.
hakre
Хорошее дополнение. Я вижу, что WP_Queryтакже есть $post_countпеременная, вы можете использовать это вместо count($the_query->posts). Зак, ты можешь "не принять" мой ответ и принять другой, если он лучше решил твою проблему.
Ян Фабри
@ Ян - Я бы предпочел инкапсулированную переменную глобальной, потому что это увеличивает модульность. Но приятно знать, что есть один.
hakre
0

Добавьте get_columns_array()функцию в ваш function.php. Затем вы можете легко перебрать свои столбцы:

В вашей теме вы затем цикл foreach над столбцами:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<?php foreach(get_columns_array($post_count) as $column_count) : ?>
    <ul>
        <?php while ($column_count--) : $the_query->the_post(); ?>
        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
    </ul>
<?php endforeach; wp_reset_postdata(); ?>

Я установил размер столбца по умолчанию равным 10. Вы можете использовать второй параметр, чтобы установить размер столбца самостоятельно. Нравится 7 get_columns_array($post_count, 7);.

hakre
источник
0

Вот еще один подход, который вы можете использовать:

$article = 0;

<?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
        <?php $article = $article + 1; ?>
        <?php if ($article % 3 == 1) echo '<div class="row-fluid">';  ?>
            <div class="span4">
            <h2><a href="<?php esc_url( the_permalink() ); ?>" title="Permalink to <?php the_title(); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
            </div><!--/span-->
        <?php if ($article % 3 == 0) echo '</div><!--/row-->';  ?>
    <?php endwhile;?>
<?php else: ?>
<h2>...</h2>
<?php endif; ?>
Винсент
источник