วิธีการแบ่งลูปเป็นหลายคอลัมน์


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 ส่งคืน</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

คำตอบ:


21

สร้างคอลัมน์สำหรับแบบสอบถามของคุณและแสดงผลได้ง่าย

ในธีมอาจมีประโยชน์มากกว่าที่จะมีบางสิ่งที่เหมาะสมกับเทมเพลตแท็กและลูป คำตอบแรกของฉันไม่ได้มุ่งเน้นที่มาก นอกจากนี้ฉันคิดว่ามันซับซ้อนเกินไปสำหรับการนำไปใช้อย่างรวดเร็ว

วิธีที่ง่ายขึ้นที่โผล่เข้ามาในใจของฉันคือการขยาย"วง"กับคอลัมน์และมาถึงวิธีการแก้ปัญหานี้:

WP_Query_Columnsวัตถุ "ขยาย" ใด ๆ แบบสอบถาม WP มาตรฐานที่มี colums ที่สามารถได้อย่างง่ายดายซ้ำมากกว่า พารามิเตอร์แรกคือตัวแปรแบบสอบถามและพารามิเตอร์ที่สองคือจำนวนรายการที่จะแสดงต่อคอลัมน์:

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

โชคดีที่มีโค้ดเราสามารถตั้งค่าทั้งหมดเหล่านี้ในตัวแปรและสร้างรหัสที่คำนวณตามความต้องการของเรา

และบางครั้งเราก็ไม่สามารถตอบคำถามทุกข้อได้ตั้งแต่ต้น สำหรับ exmaple การนับจำนวนรายการทั้งหมด: มีการนับจำนวนที่แน่นอนหลายรายการที่ตรงกับจำนวนคอลัมน์ทั้งหมดหรือไม่

แม้คำตอบของ 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

@hakre: $the_query->the_post()จะเขียนทับ$postตัวแปรทั่วโลกและwp_reset_query()เรียกคืนสิ่งนี้ (โดยการโทรwp_reset_postdata()- ซึ่งอาจเพียงพอสำหรับตัวเองด้วย)
Jan Fabry

โอเคฉันผสม wp_query แล้วโพสต์เล็กน้อยคิดว่ามันจะทำอะไร$wp_queryแต่$the_queryถูกใช้ในตัวอย่าง อย่างไรก็ตามฉันผิดฉันจะเพิ่มไปยังคำตอบที่สองเพื่อความสมบูรณ์
hakre

คุณไม่ได้คิดบัญชีสำหรับรายการสุดท้าย ถ้าห่วงสิ้นสุดที่หารจำนวน 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

นอกจากนี้ที่ดี ผมเห็นว่าWP_Queryยังมีตัวแปรที่คุณสามารถใช้ที่แทน$post_count count($the_query->posts)Zac, คุณสามารถ "รับรู้" คำตอบของฉันและยอมรับอีกถ้ามันแก้ปัญหาของคุณได้ดีขึ้น
Jan Fabry

@Jan - ฉันต้องการตัวแปรที่ห่อหุ้มมากกว่าหนึ่งทั่วโลกเพราะสิ่งนี้จะเพิ่ม modularity แต่ดีที่รู้ว่ามี
hakre

0

เพิ่มget_columns_array()ฟังก์ชั่นของคุณ function.php จากนั้นคุณสามารถทำซ้ำคอลัมน์ของคุณได้อย่างง่ายดาย:

ในชุดรูปแบบของคุณจากนั้นคุณจะวนซ้ำคอลัมน์ต่างๆ:

<?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 คุณสามารถใช้พารามิเตอร์ที่สองเพื่อกำหนดขนาดของคอลัมน์ด้วยตัวคุณเอง เหมือนที่ get_columns_array($post_count, 7);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; ?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.