So teilen Sie eine Schleife in mehrere Spalten


11

Wenn ich eine Schleife habe, die von einer Kategorieabfrage ausgeht, wie:

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

Wie würde ich eine if-Klausel erstellen, die die Liste in einem bestimmten Intervall unterbricht und eine neue startet? Geben Sie zum Beispiel beim 10. Beitrag a zurück </ul>und beginnen Sie <ul>um 11 Uhr einen neuen .

Dies ist falsch, aber um mein Ziel zu veranschaulichen:

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

Was ist der richtige Weg, um diese Logik in die Schleife aufzunehmen?


Ich habe meine Antwort mit etwas aktualisiert, das im Allgemeinen einfach zu bedienen und zu testen sein sollte.
hakre

Antworten:


21

Erstellen Sie Spalten für Ihre Abfrage und einfache Anzeige

In Themen ist es wahrscheinlich nützlicher, etwas zu haben, das gut in Vorlagen-Tags und die Schleife passt. Meine erste Antwort konzentrierte sich nicht so sehr. Außerdem fand ich es etwas zu kompliziert für eine schnelle Adoption.

Ein einfacherer Ansatz, der mir in den Sinn kam, bestand darin, "die Schleife" mit Spalten zu erweitern und kam bisher zu dieser Lösung:

Ein WP_Query_Columns- Objekt "erweitert" jede Standard-WP-Abfrage um Spalten, die leicht durchlaufen werden können. Der erste Parameter ist die Abfragevariable und der zweite Parameter ist die Anzahl der Elemente, die pro Spalte angezeigt werden sollen:

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

Um es zu verwenden, fügen Sie einfach die WP_Query_Columns-Klasse aus dieser Liste zu Ihrer Themes function.php hinzu.

Erweiterte Verwendung

Wenn Sie die Spaltennummer benötigen, die Sie gerade anzeigen (z. B. für einige gerade / ungerade CSS-Klassen, können Sie diese auch von foreach abrufen:

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

Und die Gesamtzahl der Spalten ist ebenfalls verfügbar:

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

Zehnundzwanzig Beispiel

Ich könnte schnell zehnundzwanzig Themen für einen Test hacken und auf diese Weise Überschriften über jeder Schleife hinzufügen. Es ist in loop.php eingefügt, der Anfang ist der Code des Themas:

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

Für eine längere Antwort:

(So ​​bin ich im Grunde zu den obigen Dingen gekommen, erkläre aber besser, wie man das Problem tatsächlich mit einfachen mathematischen Operationen löst. Meine neue Lösung besteht darin, über etwas Vorberechnetes zu iterieren.)

Es hängt ein wenig davon ab, wie viel Sie tatsächlich benötigen, um das Problem zu lösen.

Wenn beispielsweise die Anzahl der Elemente pro Spalte gleich eins ist, ist dies sehr einfach:

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

Selbst mit diesem einfachen Code kann man sehen, dass mehrere Entscheidungen getroffen werden müssen:

  • Wie viele Elemente befinden sich in einer Spalte?
  • Wie viele Artikel gibt es insgesamt?
  • Gibt es eine neue Spalte zu starten?
  • Und gibt es eine Spalte zum Beenden?

Die letzte Frage ist für die HTML-Ausgabe ziemlich interessant, da Sie wahrscheinlich nicht nur Elemente, sondern auch die Spalte mit HTML-Elementen einschließen möchten.

Glücklicherweise können wir mit Code all dies in Variablen festlegen und Code erstellen, der immer unseren Anforderungen entspricht.

Und manchmal können wir sogar nicht jede Frage von Anfang an beantworten. Zum Beispiel die Anzahl der Gesamtelemente: Gibt es einige, mehrere, eine genaue Anzahl, die mit einer ganzzahligen Anzahl von Spalten insgesamt übereinstimmt?

Selbst die Antwort von Jan Fabry funktioniert in einigen Fällen (wie in meinem obigen Beispiel für das Szenario mit einem Element pro Spalte). Möglicherweise interessieren Sie sich für etwas, das für eine beliebige Anzahl von von WP_Query zurückgegebenen Elementen funktioniert.

Zuerst für die Mathematik:

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

Dieser Code wird nicht ausgeführt. Lassen Sie uns dies in ein einfaches Textbeispiel umwandeln

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

Dies läuft tatsächlich und gibt bereits einige Ausgaben aus:

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

Dies simuliert bereits ziemlich gut, wie es in einer WordPress-Vorlage aussehen könnte :

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

(Ich habe das letzte Beispiel nicht in einer WP-Umgebung ausgeführt, aber es sollte zumindest syntaktisch korrekt sein.)


2

Dies ist eher eine allgemeine Programmierfrage, aber hier ist die Grundidee:

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

Die Modulo-Operation ist im Grunde die mathematische Antwort. In Ihrem Beispiel fehlt jedoch die semantische HTML-Ausgabe. Ich habe in meiner Antwort etwas Ähnliches vorgeschlagen, da Sie sich vorstellen können, dass es etwas länger
gedauert hat

wp_reset_query();ist nicht mit der Variablen $ the_query verbunden. Das wird überhaupt nicht benötigt, oder?
hakre

@hakre: $the_query->the_post()Überschreibt die globale $postVariable und wp_reset_query()stellt sie wieder her (durch Aufrufen wp_reset_postdata()- was könnte auch alleine ausreichen?).
Jan Fabry

Okay, ich habe wp_query irgendwie gemischt und ein bisschen gepostet, dachte, es würde etwas bewirken $wp_query, $the_querywurde aber im Beispiel verwendet. Ich habe mich jedoch geirrt und werde es der Vollständigkeit halber meiner zweiten Antwort hinzufügen.
hakre

Sie berücksichtigen nicht den letzten Artikel. Wenn die Schleife mit einer durch 10 teilbaren Zahl endet, erhalten Sie einen leeren Satz von <ul></ul>.
Dan Gayle

1

Es ist nicht erforderlich, eine separate Variable zum Zählen zu erstellen, da die Abfragevariable diese bereits zählt bei : $wp_query->current_post. Außerdem müssen Sie den endgültigen Eintrag in der Liste berücksichtigen, damit <ul></ul>Ihr Markup nicht leer ist .

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

Notiert. Beispiel hinzugefügt.
Dan Gayle

Cool, ich mag den Zusatz, weil das leere ´ <ul> </ ul> `jetzt nur für 0 Beiträge ist (aber für diejenigen, die es noch sind) - aber nach dem, was ich heute gelernt habe, ist diese Form die kleinste mit o Einführung einer neuen Funktion.
hakre

Schöne Ergänzung. Ich sehe, dass es WP_Queryauch eine $post_countVariable gibt, die Sie stattdessen verwenden können count($the_query->posts). Zac, du kannst meine Antwort "inakzeptieren" und eine andere akzeptieren, wenn sie dein Problem besser löst.
Jan Fabry

@Jan - Ich würde die gekapselte Variable der globalen vorziehen, da dies die Modularität erhöht. Aber gut zu wissen, dass es einen gibt.
hakre

0

Fügen Sie die get_columns_array()Funktion Ihrer function.php hinzu. Sie können dann einfach über Ihre Spalten iterieren:

In Ihrem Thema führen Sie dann jede Schleife über die Spalten durch:

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

Ich habe die Standardgröße einer Spalte auf 10 festgelegt. Mit dem zweiten Parameter können Sie die Größe einer Spalte selbst festlegen. Wie zu 7 : get_columns_array($post_count, 7);.


0

Hier ist ein weiterer Ansatz, den Sie verfolgen können:

$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; ?>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.