Cách chia vòng lặp thành nhiều cột


11

Nếu tôi có một vòng lặp chạy từ một truy vấn thể loại như:

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

Làm thế nào tôi có thể tạo một mệnh đề if phá vỡ danh sách ở một khoảng nhất định và bắt đầu một mệnh đề mới. Vì vậy, ví dụ ở bài thứ 10, hãy trả lại một </ul>và bắt đầu một bài mới <ul>vào lúc 11.

Điều này không chính xác nhưng để minh họa mục tiêu của tôi:

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

Cách chính xác để đưa logic này vào vòng lặp là gì?


Tôi đã cập nhật câu trả lời của mình với một cái gì đó thường dễ sử dụng và thử nghiệm.
hakre

Câu trả lời:


21

Tạo Cột cho truy vấn của bạn và hiển thị dễ dàng

Trong các chủ đề có lẽ hữu ích hơn để có một cái gì đó phù hợp với thẻ mẫu và vòng lặp. Câu trả lời đầu tiên của tôi không tập trung vào điều đó nhiều. Ngoài ra, tôi nghĩ rằng nó hơi phức tạp để áp dụng nhanh chóng.

Một cách tiếp cận dễ dàng hơn xuất hiện trong tâm trí của tôi là mở rộng "vòng lặp" với các cột và đến với giải pháp này cho đến nay:

Một đối tượng WP_Query_Columns "mở rộng" bất kỳ truy vấn WP tiêu chuẩn nào với các colums có thể dễ dàng lặp lại. Tham số đầu tiên là biến truy vấn và tham số thứ hai là số lượng mục được hiển thị trên mỗi cột:

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

Để sử dụng nó, chỉ cần thêm lớp WP_Query_Columns từ ý chính này vào chủ đề function.php của bạn.

Sử dụng nâng cao

Nếu bạn cần số cột mà bạn hiện đang hiển thị (ví dụ: đối với một số lớp CSS chẵn / lẻ, bạn cũng có thể lấy số đó từ foreach:

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

Và tổng số cột cũng có sẵn:

<?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>...

Hai mươi mười ví dụ

Tôi có thể nhanh chóng hack hai mươi mười chủ đề cho một bài kiểm tra và thêm các tiêu đề trên bất kỳ vòng lặp nào theo cách này. Nó được chèn vào loop.php, phần đầu là mã của chủ đề:

<?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.
    ...

Để có câu trả lời dài hơn:

(về cơ bản là cách tôi đến với những thứ ở trên, nhưng giải thích rõ hơn cách giải quyết vấn đề bằng các phép toán đơn giản. Giải pháp mới của tôi là lặp lại một cái gì đó được tính toán trước.)

Nó phụ thuộc một chút bạn thực sự cần bao nhiêu để giải quyết vấn đề.

Ví dụ: nếu số lượng mục trên mỗi cột bằng một, thì điều này rất đơn giản:

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

Ngay cả với mã đơn giản đó, có thể thấy rằng có nhiều quyết định được đưa ra:

  • Có bao nhiêu mục trong một cột?
  • Tổng cộng có bao nhiêu mặt hàng?
  • Có một cột mới để bắt đầu?
  • Và có một cột để kết thúc?

Câu hỏi cuối cùng khá thú vị đối với đầu ra HTML vì có lẽ bạn muốn gửi kèm không chỉ các mục mà cả cột có các phần tử html.

May mắn thay với mã, chúng ta có thể đặt tất cả các biến này trong các biến và tạo mã luôn tính toán theo nhu cầu của chúng ta.

Và đôi khi, chúng ta thậm chí không thể trả lời mọi câu hỏi ngay từ đầu. Đối với exmaple, tổng số mục: Có bất kỳ, một số, nhiều, một số đếm chính xác phù hợp với tổng số cột trong tổng số không?

Ngay cả câu trả lời của Jan Fabry cũng có thể hoạt động trong một số trường hợp (như ví dụ của tôi ở trên đối với kịch bản một mục trên mỗi cột), bạn có thể quan tâm đến điều gì đó hoạt động cho bất kỳ số lượng mục nào được trả về bởi WP_Query.

Đầu tiên cho môn toán:

//
// 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

Mã đó không chạy, vì vậy hãy đưa nó vào một ví dụ văn bản đơn giản

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

Điều này thực sự chạy và đã thực hiện một số đầu ra:

<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.

Này mô phỏng đã khá tốt như thế nào nó có thể trông giống như trong một mẫu 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();
?>

(Tôi chưa thực hiện ví dụ cuối cùng trong môi trường WP, nhưng ít nhất nó phải đúng về mặt cú pháp.)


2

Đây là một câu hỏi lập trình chung, nhưng đây là ý tưởng cơ bản:

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

Các hoạt động modulo về cơ bản là câu trả lời toán học. Nhưng ví dụ của bạn thiếu đầu ra HTML ngữ nghĩa. Tôi đã đề xuất một cái gì đó tương tự trong câu trả lời của tôi, như bạn có thể tưởng tượng nó đã mất thêm thời gian;)
hakre

wp_reset_query();không liên quan đến biến $ the_query. Điều này là không cần thiết, phải không?
hakre

@hakre: $the_query->the_post()sẽ ghi đè lên $postbiến toàn cục và wp_reset_query()khôi phục biến này (bằng cách gọi wp_reset_postdata()- cũng có thể là đủ?).
Jan Fabry

Được rồi, bằng cách nào đó tôi đã trộn wp_query và đăng một chút, nghĩ rằng nó sẽ làm gì đó $wp_querynhưng $the_queryđược sử dụng trong ví dụ. Tuy nhiên, tôi đã sai, tôi sẽ thêm nó vào câu trả lời thứ hai của mình cho đầy đủ.
hakre

Bạn không hạch toán cho mục cuối cùng. Nếu vòng lặp kết thúc trên một số chia hết cho 10, bạn sẽ nhận được một tập hợp trống <ul></ul>.
Dan Gayle

1

Không cần tạo một var riêng để đếm, vì var truy vấn đã đếm nó tại : $wp_query->current_post. Ngoài ra, bạn cần tính đến mục cuối cùng trong danh sách để bạn không có chỗ trống <ul></ul>trong đánh dấu của bạn.

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

Lưu ý Ví dụ được thêm vào.
Dan Gayle

Thật tuyệt, tôi thích phần bổ sung vì trống <ul> </ ul> `hiện chỉ dành cho 0 bài viết (nhưng đối với những bài viết đó vẫn còn) - nhưng từ những gì tôi đã học ngày hôm nay, hình thức đó là nhỏ nhất w / o giới thiệu một chức năng mới.
hakre

Bổ sung tốt đẹp. Tôi thấy rằng WP_Querycũng có một $post_countbiến, bạn có thể sử dụng thay vì count($the_query->posts). Zac, bạn có thể "không chấp nhận" câu trả lời của tôi và chấp nhận câu trả lời khác nếu nó giải quyết vấn đề của bạn tốt hơn.
Jan Fabry

@Jan - Tôi thích biến đóng gói hơn biến toàn cục vì điều này làm tăng tính mô đun. Nhưng tốt để biết có một.
hakre

0

Thêm get_columns_array()chức năng vào hàm.php của bạn. Sau đó, bạn có thể dễ dàng lặp lại qua các cột của mình:

Trong chủ đề của bạn, sau đó bạn tìm kiếm vòng lặp trên các cột:

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

Tôi đặt kích thước mặc định của cột thành 10. Bạn có thể sử dụng tham số thứ hai để tự đặt kích thước của cột. Thích 7 : get_columns_array($post_count, 7);.


0

Đây là một cách tiếp cận khác bạn có thể thực hiện:

$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; ?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.