it-swarm.com.de

Alle Posts in der Kategorie anzeigen, mit bestimmten Tag-Posts oben

Frage umformulieren

Ich muss Posts in der Schleife für meine Kategorie car bestellen. Was ich brauche, wenn ich die Kategorieseite von car besuche, müssen zuerst alle Beiträge mit dem Tag BMW und dann die anderen Beiträge ohne den Tag BMW angezeigt werden.

Wenn mein posts_per_page so eingestellt ist, dass 10 Posts angezeigt werden und ich auf Seite 1 bin und drei der zehn Posts mit dem Tag BMW versehen sind, müssen diese drei Posts zuerst angezeigt werden, und der Rest folgt diesen drei Posts. Wenn ich klicke und auf Seite zwei gehe, gilt das Gleiche. Wenn ich 5 dieser 10 Beiträge mit dem Tag BMW habe, müssen sie erneut vor den anderen 5 Beiträgen erscheinen.

Ist das möglich?

3
PreeT

Hier ist eine vereinfachte Kombination aus guten Antworten von @PieterGoosen und @ialocin unter Verwendung des Hooks loop_start:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_category( 'car' ) )
        usort( $q->posts, function( $a, $b ){
            return -1 * has_tag( 'bmw', $a ) + 1 * has_tag( 'bmw', $b );            });
}, 10, 2 );

Wir könnten dieselbe Methode auch für den the_posts-Filter verwenden.

Update:

Um Beiträge auf der Homepage nach dem ersten Kategorienamen zu sortieren, können wir zum Beispiel versuchen:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_home() )
        usort( $q->posts, function( $a, $b ){
            return strcasecmp( 
                get_the_category( $a->ID )[0]->name, 
                get_the_category( $b->ID )[0]->name 
            );
        });
}, 10, 2 );

wobei wir strcasecmp zum Vergleich von Strings ohne Berücksichtigung der Groß- und Kleinschreibung verwenden.

5
birgire

Sie können diese Art der Sortierung nicht innerhalb der Schleife durchführen. Sie können jedoch eine eigene Funktion schreiben

Hier ist meine Lösung: PS! Needs PHP 5.4+

SCHRITT 1

Erstellen Sie eine Funktion mit dem Namen wpse161553_loop_sort($tag=''). Dies funktioniert mit einem einzelnen Tag mit der Hauptabfrage.

SCHRITT 2

Sie müssen die Post-Objekte aus der Hauptabfrage abrufen. Sie sind bereits verfügbar und können nur über $wp_query->posts; aufgerufen werden. (Eine vollständige Liste der verfügbaren Objekte und deren Zugriff finden Sie unter WP_Post ).

SCHRITT 3

Erstellen und starten Sie einen neuen Zähler. Dieser Zähler wird später verwendet, um die Array-Schlüssel von $wp_query->posts; zu ändern.

SCHRITT 4

Holen Sie sich die Option posts_per_page im Backend. Dieser Wert wird dem Zähler für alle Posts hinzugefügt, die nicht das gewünschte Tag haben. Dadurch werden alle diese Posts über die gewünschten Tag-Posts hinaus verschoben

SCHRITT 5

Verwenden Sie in der Schleife has_tag() , um jeden Beitrag mit dem gewünschten Tag zu vergleichen. Wenn ein Beitrag ein gewünschtes Tag hat, schieben Sie den aktuellen Zählerwert unverändert auf ein Array ($c). Wenn ein Beitrag nicht über das gewünschte Tag verfügt, verschieben Sie den Wert des aktuellen Zählers plus den Wert für posts_per_page auf $c.

SCHRITT 6

Verwenden Sie array_combine , um die beiden Arrays miteinander zu kombinieren. Das neu erstellte Array $c ersetzt die Array-Schlüssel des Arrays von Posts

STEP 7

Verwenden Sie ksort , um das mit array_combine erstellte Array nach den neuen Schlüsseln zu sortieren. Dadurch wird das Array nun so sortiert, dass die Beiträge nach dem Datum des Beitrags sortiert werden. Außerdem werden zuerst die Beiträge des gewünschten Tags und dann die restlichen Beiträge angezeigt

Schritt 8

Verwenden Sie array-values , um die Schlüssel zurückzusetzen, um mit 0 zu beginnen und numerisch um eins zu erhöhen

SCHRITT 9

Spulen Sie die Schleife zurück, damit wir sie erneut ausführen können

SCHRITT 10

Deaktivieren Sie das ursprüngliche Array in $wp_query->posts und ersetzen Sie es durch das neu erstellte Array. $wp_query->posts enthält jetzt ein Array mit der neu bestellten Post-Bestellung

ALLES ZUSAMMEN JETZT !!

Der folgende Code geht in deine functions.php

function wpse161553_loop_sort($tag='') {
    global $wp_query;
    $posts = $wp_query->posts; // Gets all post data from the main query

    $c = []; // Going to hold an array of new keys for later use
    if ( have_posts() ) {
        $count = 0; //Start the counter
        $ppp = get_option('posts_per_page'); // Gets the backend posts per page option set. Will be used in conjustion with the counter

        while ( have_posts() ) {
            the_post();
                if( '' != $tag && has_tag($tag)) { // This will be the tag to test against, your desired tag
                    $c[] = $count++;
                }else{
                    $c[] = $ppp + $count++; // Adds posts per page value to each count to advance posts without desired tag past desired tag
                }
        }
    } 

    $posts_reordered  = array_combine( $c, $posts ); // Reset each post from main query's key with the new keys created by $c
        $posts_sorted = ksort($posts_reordered); // Sort the new array according to key
    $posts_reordered  = array_values($posts_reordered); // Reset keys to start at zero and increment by one

    rewind_posts(); // Reset the loop so we can run the loop again

    unset($wp_query->posts); //unset the original $wp_query->posts object array
    $wp_query->posts = $posts_reordered; // Set $wp_query->posts to the new reordered array

}

WIE WIRD ES ANGEWENDET

Fügen Sie in Ihrer category.php oder in einer beliebigen Vorlage Folgendes direkt über der Schleife ein. Sie müssen nichts mehr ändern

wpse161553_loop_sort( 'NAME OF THE TAG TO APPEAR FIRST' );

dabei ist NAME OF THE TAG TO APPEAR FIRST der Name des gewünschten Tags, dessen Beiträge zuerst angezeigt werden

3
Pieter Goosen

Nur ein kurzer Entwurf einer Idee, also passen Sie auf, dass ich das nicht vollständig durchdacht und getestet habe. Ich bin mir jedoch sicher, dass Sie auf diese Weise Sortieraktionen durchführen können. Ok, ich dachte, warum nicht in the_posts einbinden und usort verwenden, um die Sortierung durchzuführen. Der Rest, insbesondere die Bedingungen, dienen nur dazu, sicherzustellen, dass dies nicht bei jeder Abfrage durchgeführt wird und vom tatsächlichen Anwendungsfall abhängt, sodass dies entsprechend angepasst werden muss.

add_action(
    'the_posts',
    'wpse161553_posts_with_tags_on_top_of_category',
    10,
    2
);
function wpse161553_posts_with_tags_on_top_of_category(
    $posts,
    $wp_query
) {
    // we want this for one specific category
    $the_category = 'abc';
    // we want the post with this tag on top 
    $the_tag      = 'xyz';

    if (
        $wp_query->is_main_query()
        && is_category( $the_category )
    ) {
        // getting an array of post ids from category with tag
        $posts_with_tag = new WP_Query(
            array(
                'category_name' => $the_category,
                'tag'           => $the_tag,
                'fields'        => 'ids'
            )
        );  
        // performing usort on referenced posts object
        usort(
            $posts,
            function (
                $post
            ) use (
                $posts_with_tag
            ) {
                // puts posts from the $posts_with_tag->posts array to the top
                if(
                    in_array (
                        $post->ID,
                        (array) $posts_with_tag->posts 
                     )
                ) {
                    return -1;
                } else {
                    return 1;
                }
            }
        );
    }

    return $posts;
} 
2
Nicolai