如何将循环分成多列


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>";
        }

将这种逻辑包含在循环中的正确方法是什么?


我用通常应该易于使用和测试的内容更新了答案。
hakre 2011年

Answers:


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类添加到主题function.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元素的列括起来。

幸运的是,使用代码,我们可以在变量中设置所有这些代码,并创建始终可以满足我们需求的代码。

有时甚至,我们甚至无法从一开始就回答所有问题。例如,总项目数:是否有某个总的整数与整数列匹配的某个,多个准确的计数?

甚至Jan Fabry的答案在某些情况下也可能有效(就像我上面的示例对每个列一个项目的情况一样),您可能会对某些适用于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环境中执行最后一个示例,但至少在语法上应正确。)


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输出。我已经在回答中提出了类似的建议,因为您可以想象它花费了更多的时间;)
hakre

wp_reset_query();与$ the_query变量无关。根本不需要这个,对吗?
hakre 2011年

@hakre:$the_query->the_post()将覆盖全局$post变量,并wp_reset_query()通过调用wp_reset_postdata()-单独恢复该变量来恢复该变量。
Jan Fabry

好吧,我以某种方式混合了wp_query并发布了一些内容,以为它可以做些事,$wp_query但是$the_query在示例中使用了它。但是,我错了,为了完整性,我将其添加到第二个答案中。
hakre 2011年

您没有考虑最后一项。如果循环结束于一个可被10整除的数字,则将得到一个空集<ul></ul>
Dan Gayle

1

无需创建单独的var进行计数,因为查询var已在处对其进行计数$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>";
?>

注意。添加示例。
Dan Gayle

很酷,我喜欢添加内容,因为空的«<ul> </ ul>`现在仅适用于0个帖子(但对于那些帖子仍然如此)-但是从我今天所学的知识来看,这种形式是最小的w / o引入新功能。
hakre 2011年

不错的补充。我看到它WP_Query也有一个$post_count变量,您可以使用而不是count($the_query->posts)。Zac,如果可以更好地解决您的问题,则可以“不接受”我的答案,也可以接受另一个答案。
Jan Fabry'2

@Jan-我更喜欢封装变量而不是全局变量,因为这会增加模块化。但是很高兴知道有一个。
hakre 2011年

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


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; ?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.