Cara membagi loop menjadi beberapa kolom

11

Jika saya memiliki loop yang berjalan dari permintaan kategori seperti:

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

Bagaimana saya membuat klausa if yang memecah daftar pada interval tertentu, dan memulai yang baru. Jadi misalnya di pos ke 10, kembalikan </ul>dan mulai yang baru <ul>di 11.

Ini tidak benar tetapi untuk menggambarkan tujuan saya:

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

Apa cara yang benar untuk memasukkan logika ini ke dalam loop?

zac
sumber
Saya memperbarui jawaban saya dengan sesuatu yang umumnya mudah digunakan dan diuji.
hakre

Jawaban:

21

Buat Kolom untuk kueri Anda dan tampilan yang mudah

Dalam tema mungkin lebih bermanfaat untuk memiliki sesuatu yang cocok dengan tag templat dan loop. Jawaban pertama saya tidak terlalu fokus pada itu. Selain itu saya pikir itu agak terlalu rumit untuk adopsi cepat.

Pendekatan yang lebih mudah yang muncul di pikiran saya adalah untuk memperluas "loop" dengan kolom dan sampai pada solusi ini sejauh ini:

Sebuah WP_Query_Columns keberatan "meluas" setiap permintaan WP standar dengan colums yang dapat dengan mudah iterasi berakhir. Parameter pertama adalah variabel kueri dan parameter kedua adalah jumlah item yang akan ditampilkan per kolom:

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

Untuk menggunakannya, cukup tambahkan kelas WP_Query_Columns dari intisari ini ke function.php tema Anda.

Penggunaan Lanjutan

Jika Anda memerlukan nomor kolom yang saat ini Anda tampilkan (misalnya untuk beberapa kelas CSS genap / ganjil, Anda bisa mendapatkannya dari foreach juga:

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

Dan jumlah kolom juga tersedia:

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

Dua Puluh Sepuluh Contoh

Saya dapat dengan cepat meretas dua puluh sepuluh tema untuk pengujian dan menambahkan tajuk utama di atas setiap loop dengan cara ini. Ini dimasukkan ke dalam loop.php, awalnya adalah kode tema:

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

Untuk jawaban yang lebih panjang:

(itu pada dasarnya bagaimana saya sampai pada hal-hal di atas, tetapi menjelaskan lebih baik bagaimana sebenarnya memecahkan masalah dengan operasi matematika sederhana. Solusi baru saya adalah untuk mengulangi sesuatu yang sudah dihitung sebelumnya.)

Tergantung sedikit seberapa banyak Anda benar-benar perlu menyelesaikan masalah.

Misalnya, jika jumlah item per kolom sama dengan satu, ini sangat sederhana:

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

Bahkan dengan kode sederhana itu, dapat dilihat bahwa ada beberapa keputusan yang harus diambil:

  • Berapa banyak item dalam satu kolom?
  • Ada berapa banyak barang di sana?
  • Apakah ada kolom baru untuk memulai?
  • Dan apakah ada kolom untuk diakhiri?

Pertanyaan terakhir cukup menarik untuk output HTML karena Anda mungkin ingin menyertakan tidak hanya item tetapi juga kolom dengan elemen html.

Untungnya dengan kode, kita dapat mengatur semua ini dalam variabel dan membuat kode yang selalu sesuai dengan kebutuhan kita.

Dan terkadang bahkan, kita bahkan tidak bisa menjawab setiap pertanyaan dari awal. Untuk exmaple, hitungan total item: Apakah ada, beberapa, beberapa, jumlah yang tepat yang cocok dengan jumlah kolom integer secara total?

Bahkan jawaban Jan Fabry mungkin berfungsi dalam beberapa kasus (seperti contoh saya di atas untuk skenario satu-item-per-kolom), Anda mungkin tertarik pada sesuatu yang berfungsi untuk sejumlah item yang dikembalikan oleh WP_Query.

Pertama untuk matematika:

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

Kode itu tidak berjalan, jadi mari kita buat itu menjadi contoh teks sederhana

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

Ini sebenarnya berjalan dan sudah melakukan beberapa output:

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

Ini mensimulasikan sudah cukup baik bagaimana itu bisa terlihat seperti di template 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();
?>

(Saya belum menjalankan contoh terakhir di lingkungan WP, tetapi setidaknya harus benar secara sintaksis.)

hakre
sumber
2

Ini lebih merupakan pertanyaan pemrograman umum, tetapi inilah ide dasarnya:

<?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();
?>
Jan Fabry
sumber
Operasi modulo pada dasarnya adalah jawaban matematika. Tetapi contoh Anda tidak memiliki output HTML semantik. Saya telah mengusulkan sesuatu yang serupa dalam jawaban saya, seperti yang dapat Anda bayangkan butuh waktu lebih lama;)
hakre
wp_reset_query();tidak terkait dengan variabel $ the_query. Ini tidak diperlukan sama sekali, kan?
hakre
@ hakre: $the_query->the_post()akan menimpa $postvariabel global , dan wp_reset_query()mengembalikan ini (dengan memanggil wp_reset_postdata()- yang juga cukup?).
Jan Fabry
Oke saya entah bagaimana mencampur wp_query dan memposting sedikit, berpikir itu akan melakukan sesuatu untuk $wp_querytetapi $the_querydigunakan dalam contoh. Namun, saya salah, saya akan menambahkannya ke jawaban kedua saya untuk kelengkapan.
hakre
Anda tidak memperhitungkan item terakhir. Jika loop berakhir pada angka yang habis dibagi 10, Anda akan mendapatkan seperangkat kosong <ul></ul>.
Dan Gayle
1

Tidak perlu untuk membuat var terpisah untuk menghitung, sebagai var permintaan sudah menghitung di: $wp_query->current_post. Juga, Anda perlu memperhitungkan entri terakhir dalam daftar sehingga Anda tidak memiliki kosong <ul></ul>di markup Anda.

<?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
sumber
Dicatat. Contoh ditambahkan.
Dan Gayle
Keren, saya suka penambahan itu karena kosong ´ <ul> </ul> `hanya untuk 0 posting sekarang (tetapi bagi yang masih) - tetapi dari apa yang saya pelajari hari ini, bentuk itu adalah yang terkecil dengan o memperkenalkan fungsi baru.
hakre
Tambahan yang bagus. Saya melihat bahwa WP_Queryjuga memiliki $post_countvariabel, Anda dapat menggunakannya sebagai ganti count($the_query->posts). Zac, Anda dapat "tidak menerima" jawaban saya dan menerima jawaban lain jika itu memecahkan masalah Anda dengan lebih baik.
Jan Fabry
@ Jan - Saya lebih suka variabel yang dienkapsulasi daripada yang global karena ini meningkatkan modularitas. Tapi senang tahu ada satu.
hakre
0

Tambahkan get_columns_array()fungsi ke function.php Anda. Anda kemudian dapat dengan mudah beralih di atas kolom Anda:

Dalam tema Anda, Anda kemudian foreach loop atas kolom:

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

Saya menetapkan ukuran default sebuah kolom menjadi 10. Anda dapat menggunakan parameter kedua untuk mengatur ukuran kolom Anda sendiri. Suka 7: get_columns_array($post_count, 7);.

hakre
sumber
0

Berikut adalah pendekatan lain yang dapat Anda ambil:

$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; ?>
Vincent
sumber