Support » Themes » Liste zufällig laden und einen Bestimmten Post immer weiter hinten anzeigen

  • Gelöst herzla

    (@herzla)


    guten Abend zusammen.
    ich glaube das ist mein erster Thread hier und ich bemühe mich mal meine Frage verständlich auszudrücken:

    wir haben einen custom-post-type mit dem Namen „partner“
    auf einer Seite zeigen wir die Liste alle Partner an und laden sie in zufälliger Reihenfolge
    das machen wir so:

    
    $args = array( 'post_type' => 'partner', 'post__not_in' => array( 856 ), 'posts_per_page' => -1, 'orderby' => 'rand' );
    $loop = new WP_Query( $args );

    wie ihr seht haben wir einen Partner immer ausgeblendet und nun möchten wir es noch bewerkstelligen, dass ein anderer bestimmter Partner in der Liste niemals als erster oder zweiter aufscheint

    direkt als query wird sich das nicht bewerkstelligen lassen, oder?

    vielen dank schön mal für die Aufmerksamkeit und für Anregungen sowiso 🙂

    • Dieses Thema wurde geändert vor 3 Wochen, 6 Tage von herzla.
    • Dieses Thema wurde geändert vor 3 Wochen, 6 Tage von herzla.
    • Dieses Thema wurde geändert vor 3 Wochen, 6 Tage von herzla.
Ansicht von 5 Antworten - 1 bis 5 (von insgesamt 5)
  • Hallo,
    das ist eher etwas für ein Forum wie z. B. https://wordpress.stackexchange.com/
    Hier befassen wir uns mehr mit Anwenderproblemen bei Nutzung von WordPress.

    Viele Grüße
    Hans-Gerd

    Zu $loop = new WP_Query( $args );:

    Eine Query ist noch keine Loop. Die Loop ist erst eine Schleife durch die Ergebnisse der Query. Deshalb würde ich die Variable z.B. $query nennen. 🤓

    Bei $query = new WP_Query( $args ); ist
    $query->posts[0]->ID die ID des ersten Posts und
    $query->posts[1]->ID die ID des zweiten Posts.

    Die kannst du in einem Array zusammenfassen:
    $top = array( $query->posts[0]->ID, $query->posts[1]->ID );

    Nun kannst du prüfen, ob in dem Array die ID des Teilnehmers vorhanden ist, der nicht auf den ersten beiden Plätzen der Liste erscheinen soll:
    if( in_array( '42', $top ) ) { … }

    Für den Fall, dass er dort auftaucht, kannst du das Array neu mischen:

    if( in_array( '42', $top ) ) {
      shuffle($query->posts);
    }

    Nun könnte das Mischen dafür sorgen, dass der Teilnehmer mit der ID 42 doch wieder auf den ersten beiden Plätzen landet. Das können wir dadurch umgehen, dass wir so lange mischen, bis sichergestellt ist, dass der Teilnehmer nicht mehr unter den ersten beiden ist:

    while( in_array( '42', $top ) ) {
      shuffle($query->posts);
    }

    In einem kleinen Test mit nur drei Teilnehmern (bei denen einer nach den Regeln der Wahrscheinlichkeitsrechnung sehr oft unter den obersten beiden ist) führte die while-Schleife allerdings zu erheblichen Performance-Problemen. Das Script mischt die Posts eben immer wieder neu. Wenn du eine größere Datenmenge hast, sinkt die Wahrscheinlichkeit, dass du den gleichen Teilnehmer beim Mischen immer wieder auf die ersten beiden Plätze setzt. Vermutlich wäre es aber geschickter, der Post aus dem Array auszuschneiden und mit array_splice() an einer anderen, zufallsgenerierten Stelle wieder einzufügen.

    Hier der Code nochmal an einem Stück:

    $query = new WP_Query( $args );
    $top = array( $query->posts[0]->ID, $query->posts[1]->ID );
    	
    while( in_array( '42', $top ) ) {
      shuffle($query->posts);
    }
    
    // The Loop
    if ( $query->have_posts() ) {
      echo '<ul>';
      while ( $query->have_posts() ) {
        $query->the_post();
        echo '<li>' . get_the_title() . '</li>';
      }
      echo '</ul>';
    } else {
      echo '<strong>Keine Bücher gefunden</strong>';
    }

    Wie Hans-Gerd schon geschrieben hat, möchten wir hier Anwendungssupport anbieten, während für Fragen zur Programmierung WordPress Stackexchange der bessere Ort ist. Es würde auch den Rahmen sprengen, wenn wir hier PHP-Grundlagen (oder HTML, JavaScript, CSS, REACT usw.) vermitteln würden.

    Viel Erfolg bei deinem Projekt.

    Nachtrag:
    Ich hab mir die Aufgabenstellung nochmal durchgelesen:

    … haben wir einen Partner immer ausgeblendet und nun möchten wir …, dass ein anderer bestimmter Partner in der Liste niemals als erster oder zweiter aufscheint

    Das lässt sich auch lösen, in dem du den „bestimmten Partner“ ebenfalls aus der Query ausschließt, mit get_posts() eine getrennte Abfrage des Posts dieses Partners machst und mit array_slice() an einem zufälligen „Array-Index + 2“ einfügst. Das ist wahrscheinlich sauberer, als die while()-Loop.

    • Diese Antwort wurde geändert vor 3 Wochen, 5 Tage von Bego Mario Garde. Grund: Nachtrag
    Thread-Starter herzla

    (@herzla)

    das ist eher etwas für ein Forum wie z. B. https://wordpress.stackexchange.com/

    aahh, danke, das erklärt so einiges 🙂

    Eine Query ist noch keine Loop

    ich liebe Antworten die so anfangen 😀
    der / die Loop fängt erst in der nächsten Zeile an 😉

    @pixolin: deine Antwort war sehr hilfreic, vielen Dank!!

    • Diese Antwort wurde geändert vor 3 Wochen, 5 Tage von herzla.
    • Diese Antwort wurde geändert vor 3 Wochen, 5 Tage von herzla.
    Thread-Starter herzla

    (@herzla)

    ..und bevor noch jemand die Endlosschlaife kopiert:
    $top muss man natürlich nach dem shuffle neu setzen und ich hab noch ein Maximum eingebaut, weil sich die Liste bei uns auch filtern lässt etc..

    $array = new WP_Query( $args );
    
    if ($array->have_posts()) {
      $top = array( $array->posts[0]->ID, $array->posts[1]->ID );
      $iShuffle = 0;
      while( $iShuffle < 5 && in_array( '47', $top ) ) {
        $iShuffle++;
        shuffle($array->posts);
        $top = array( $array->posts[0]->ID, $array->posts[1]->ID );
      }
    }
    

    funktioniert toll 🙂

    • Diese Antwort wurde geändert vor 3 Wochen, 5 Tage von herzla.

    der / die Loop fängt erst in der nächsten Zeile an

    Genau. Deswegen würde ich das Abfrageergebnis nicht $loop nennen. 🙂

    Für das Ergebnis unkritisch, aber verbessert die Lesbarkeit des Codes.

    $top muss man natürlich nach dem shuffle neu setzen

    Ähm … ups … genau.

    … und ich hab noch ein Maximum eingebaut

    Das hatte ich auch überlegt, dann aber mehr Zeit auf ein paar Code-Spielereien mit zwei Queries und array_merge() bzw. array_slice() verwendet, bis mir das zuviel wurde. Code-Beispiele hier im Forum sollen immer nur einen Denkanstoß liefern. Es war nicht mein Anspruch, eine komplette Lösung zu präsentieren.

    funktioniert toll 🙂

    Prima. Danke für deine Rückmeldung.

Ansicht von 5 Antworten - 1 bis 5 (von insgesamt 5)