it-swarm.com.de

So teilen Sie eine Schleife in mehrere Spalten

Wenn ich eine Schleife aus einer Kategorieabfrage wie folgt habe:

<?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 erstelle ich eine if-Klausel, die die Liste in einem bestimmten Intervall auflöst und eine neue startet? Geben Sie zum Beispiel bei der 10. Post einen </ul> zurück und beginnen Sie einen neuen <ul> bei 11.

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

11
zac

Erstellen Sie Spalten für Ihre Abfrage und einfache Anzeige

In Themes ist es wahrscheinlich sinnvoller, etwas zu haben, das gut in Template-Tags und die Schleife passt. Meine erste Antwort konzentrierte sich nicht so sehr darauf. Außerdem fand ich es etwas zu kompliziert für eine schnelle Einführung.

Ein einfacherer Ansatz, der mir in den Sinn kam, war das Erweitern von "the loop"mit Spalten und das Erreichen dieser Lösung:

Ein WP_Query_Columns Objekt "erweitert" jede Standardabfrage WP um Spalten, die leicht durchlaufen werden können. Der erste Parameter ist die Abfragevariable und der zweite Parameter gibt die Anzahl der Elemente an, 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; ?>

Fügen Sie dazu einfach die Klasse WP_Query_Columns aus diesem Gist zu Ihrer themes function.php hinzu.

Fortgeschrittene Nutzung

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 erhalten:

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

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 konnte schnell zehnundzwanzig Themen für einen Test hacken und auf diese Weise über jeder Schleife Überschriften einfü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:

(das ist im Grunde genommen der Grund, warum ich zu den oben genannten Dingen gekommen bin, erklärt aber besser, wie ich das Problem mit einfachen mathematischen Operationen lösen kann. Meine neue Lösung besteht darin, über etwas Vorberechnetes zu iterieren.)

Es hängt ein bisschen davon ab, wie viel Sie tatsächlich brauchen, 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 Artikel befinden sich in einer Spalte?
  • Wie viele Artikel gibt es insgesamt?
  • Gibt es eine neue Spalte zum Starten?
  • Und gibt es eine Kolumne, die zu Ende geht?

Die letzte Frage ist ziemlich interessant für die HTML-Ausgabe, 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 diese Variablen festlegen und Code erstellen, der immer unseren Anforderungen entspricht.

Und manchmal können wir nicht einmal alle Fragen von Anfang an beantworten. Zum Beispiel die Anzahl der gesamten Elemente: Gibt es mehrere exakte Elemente, die mit einer ganzzahligen Anzahl von Spalten insgesamt übereinstimmen?

Sogar die Antwort von Jan Fabry funktioniert möglicherweise in einigen Fällen (wie in meinem obigen Beispiel für das Szenario mit einem Element pro Spalte). Möglicherweise sind Sie an etwas interessiert, das für eine beliebige Anzahl von Elementen funktioniert, die von WP_Query zurückgegeben werden.

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 läuft nicht, also lassen Sie uns das in einem einfachen Textbeispiel zusammenfassen

//
// 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 führt 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 schon ziemlich gut, wie es könntein einer WordPress-Vorlage aussehen:

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

21
hakre

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

Es ist nicht erforderlich, eine separate Variable für die Zählung zu erstellen, da die Abfragevariable sie bereits bei $wp_query->current_post zählt. Außerdem müssen Sie den endgültigen Eintrag in der Liste berücksichtigen, damit Ihr Markup keinen leeren <ul></ul> enthält.

<?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>";
?>
1
Dan Gayle

Hier ist ein anderer Ansatz, den Sie wählen 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; ?>
0
Vincent

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

In Ihrem Thema suchen Sie dann nach einer Schleife über die Spalten:

<?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 setze die Standardgröße einer Spalte auf 10. Mit dem zweiten Parameter können Sie die Größe einer Spalte selbst festlegen. Wie zu 7: get_columns_array($post_count, 7);.

0
hakre