ループを複数の列に分割する方法


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

このロジックをループに含める正しい方法は何ですか?


私は答えを更新して、一般的に使いやすく、テストしやすいものにした。
ハクレ

回答:


21

クエリと簡単な表示のための列を作成する

テーマでは、テンプレートタグやループにうまく適合するものを使用する方がおそらく便利です。私の最初の答えはそれほど焦点を当てていませんでした。さらに、迅速に導入するには少し複雑すぎると思いました。

私の頭に浮かんだより簡単なアプローチは、列を使用して「ループ」を拡張することであり、これまでにこの解決策にたどり着きました。

WP_Query_Columns目的は、容易に巡回できないcolumsを持つ任意の標準WPクエリを「拡張します」。最初のパラメーターはクエリ変数で、2番目のパラメーターは列ごとに表示されるアイテムの数です。

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

これを使用するには、この要点からテーマfunction.phpにWP_Query_Columnsクラスを追加するだけです。

高度な使用法

現在表示している列番号が必要な場合(たとえば、一部の偶数/奇数の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>...

20の例

私はすぐにテストのために20のテーマをハックして、この方法でループの上に見出しを追加することができました。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.
    ...

より長い答えのために:

(これは基本的に上記のものに到達した方法ですが、単純な数学演算で実際に問題を解決する方法をよりよく説明しています。私の新しい解決策は、事前に計算されたものを反復することです。)

それはあなたが実際に問題を解決するのにどれだけ必要かによって少し異なります。

たとえば、列あたりのアイテム数が1の場合、これは非常に簡単です。

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

その単純なコードを使用しても、複数の決定を行う必要があることがわかります。

  • 1つの列にはいくつのアイテムがありますか?
  • 全部でいくつありますか?
  • 開始する新しい列はありますか?
  • そして、終了する列はありますか?

最後の質問は、おそらくアイテムだけでなくhtml要素で列も囲む必要があるため、HTML出力にはかなり興味をそそられます。

幸いなことに、コードを使用すると、これらすべてを変数に設定し、常にニーズに合わせて計算するコードを作成できます。

そして時には、私たちは最初からすべての質問に答えることさえできません。たとえば、アイテムの合計数:整数の列数と一致する正確な数はありますか?

Jan Fabryの答えでさえも機能する場合があります(上記の私の例は列ごとに1項目のシナリオで機能します)、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が、例で使用されていました。しかし、私は間違っていました。完全を期すために、2番目の回答に追加します。
ハクレ

あなたは最後の項目を考慮していません。ループが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>";
?>

了解しました。例を追加しました。
ダンゲイル、2011

空の ´<ul> </ ul> `は今のところ0件の投稿しかありません(ただし、まだそうです)ので、追加が気に入っています。 o新しい機能の導入。
hakre

素晴らしい追加。私はそれを見WP_Queryも持っている$post_count変数を、あなたはその代わりにを使用することができますcount($the_query->posts)。ザック、あなたは私の答えを「受け入れることはできません」、それがあなたの問題をよりよく解決したなら、別の答えを受け入れることができます。
Jan Fabry、2011

@Jan-モジュール化が向上するため、グローバル変数よりもカプセル化された変数を使用します。しかし、それがあることを知っておくと良いでしょう。
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に設定します。2番目のパラメーターを使用して、列のサイズを自分で設定できます。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; ?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.