web-dev-qa-db-de.com

Zwei benutzerdefinierte Schleifen, Paginierung, Offset

Ich habe zwei Schleifen mit WP_Query.

Die erste Schleife zeigt X Beiträge. Keine Paginierung.
( Schleife A )

Die zweite Schleife zeigt Y Beiträge. Mit individueller Paginierung.
( Schleife B )

Es funktioniert irgendwie; Sie können jedoch sehen, dass die zweite Schleife X Beiträge aus der ersten Schleife wiederholt. Das erste, was mir einfällt, ist, einen Versatz (gleich X) festzulegen, der jedoch die Paginierung unterbricht, und es gibt eine ganze Codex-Seite, die diesem Problem gewidmet ist. Es gibt auch eine Problemumgehung, aber das Problem ist, dass ich zwei Schleifen habe, sodass diese Problemumgehung für beide gilt.

Die Frage ist also
Wie mache ich diese Arbeit wie beabsichtigt?
Eine mögliche Lösung wäre, den Code aus Codex als "Ziel" für die zweite Schleife festzulegen, aber ich bin kein Programmierer und weiß nicht, wie ich das machen soll. Vielleicht gibt es sogar einen besseren Weg, um das zu erreichen, was ich versuche, aber mir fallen keine anderen Optionen ein.

Zusätzliche Information
1) Ich kann nicht nur einen Loop verwenden, da mein Markup kompliziert ist.
2) Der gesamte Code wurde im Internet gefunden
3) Beide Loops sind nicht durch Autoren oder Kategorien oder was auch immer eingeschränkt. Es ist immer der gleiche Inhalt mit zwei verschiedenen Layouts, die "kombiniert" werden, um wie ein einzelner "Feed" auszusehen.

und da ich nicht mehr als 2 Links posten kann, ist hier der Paginierungscode

function custom_pagination($numpages = '', $pagerange = '', $paged='') {
    if (empty($pagerange)) {
        $pagerange = 2;
    }

/**
    This first part of our function is a fallback
    for custom pagination inside a regular loop that
    uses the global $paged and global $wp_query variables.

    It's good because we can now override default pagination
    in our theme, and use this function in default quries
    and custom queries.
**/

global $paged;
if (empty($paged)) {
    $paged = 1;
}
if ($numpages == '') {
    global $wp_query;
    $numpages = $wp_query->max_num_pages;
    if(!$numpages) {
        $numpages = 1;
    }
}

/** 
    We construct the pagination arguments to enter into our paginate_links
    function. 
**/

$pagination_args = array(
    'base'            => get_pagenum_link(1) . '%_%',
    'format'          => 'page/%#%',
    'total'           => $numpages,
    'current'         => $paged,
    'show_all'        => False,
    'end_size'        => 1,
    'mid_size'        => $pagerange,
    'prev_next'       => True,
    'prev_text'       => __('«'),
    'next_text'       => __('»'),
    'type'            => 'plain',
    'add_args'        => false,
    'add_fragment'    => ''
);

$paginate_links = paginate_links($pagination_args);

if ($paginate_links) {
    echo "<nav class='custom-pagination'>";
        echo "<span class='page-numbers page-num'>Page " . $paged . " of " . $numpages . "</span> ";
        echo $paginate_links;
    echo "</nav>";
}
}

Lösung von Codex

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

//Before anything else, make sure this is the right query...
if ( ! $query->is_home() ) {
    return;
}

//First, define your desired offset...
$offset = 1;

//Next, determine how many posts per page you want (we'll use WordPress's settings)
$ppp = get_option('posts_per_page');

//Next, detect and handle pagination...
if ( $query->is_paged ) {

    //Manually determine page query offset (offset + current page (minus one) x posts per page)
    $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );

    //Apply adjust page offset
    $query->set('offset', $page_offset );

}
else {

    //This is the first page. Just use the offset...
    $query->set('offset',$offset);

}
}


add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {

//Define our offset again...
$offset = 1;

//Ensure we're modifying the right query object...
if ( $query->is_home() ) {
    //Reduce WordPress's found_posts count by the offset... 
    return $found_posts - $offset;
}
return $found_posts;
}
1
Colton

Ich kann nicht nur einen Loop verwenden, da mein Markup so kompliziert ist.

Auszeichnung, egal wie kompliziert, sollte niemals eine gültige Grundlage für die Entscheidung sein, mehrere Schleifen auszuführen. Mehrfachschleifen sollten immer nur verwendet werden, wenn es absolut keine anderen Mittel gibt, um ein bestimmtes Ergebnis zu erzielen, und dies ist fast immer dann der Fall, wenn pro Abfrageargument unterschiedliche Ergebnisse benötigt werden, z. B. unterschiedliche Beiträge pro Seite und Beitragstyp.

Beide Loops sind nicht durch Autoren oder Kategorien oder was auch immer eingeschränkt

Die obige Anweisung überprüft auch nicht die Verwendung einer zweiten Schleife. Basierend auf dieser Aussage benötigen wir nur eine Schleife, unabhängig davon, wie kompliziert Ihr Markup ist

Wie die Ergebnisse einer bestimmten Abfrage angezeigt werden, kann immer folgendermaßen geändert werden

  • rewind_posts(), mit der Sie die Schleife je nach Bedarf ein zweites, drittes oder hundertstes Mal wiederholen können

  • benutzerdefinierte Zähler oder der eingebaute Schleifenzähler, der Beiträge zählt und Ihnen ermöglicht, etwas anderes zu tun, wenn der Schleifenzähler/benutzerdefinierte Zähler eine bestimmte Zahl erreicht

  • bedingte Tags/Anweisungen, mit denen bestimmte Posts gemäß bestimmten Bedingungen (z. B. Post-Typ oder Kategorie) als Ziel ausgewählt werden können

  • filter wie der the_posts, mit dem Sie das Array der zurückgegebenen Posts ändern können, einschließlich Hinzufügen/Entfernen und/oder Neuanordnen von Posts

  • normale PHP -Funktionen wie usort(), mit denen das zurückgegebene Array von Posts sortiert werden kann, bevor sie auf dem Bildschirm ausgegeben werden

  • wir können die Hauptabfrage jederzeit mit pre_get_posts manipulieren, um anzuzeigen, was wir wollen

Dies sind nur einige Optionen, die Sie verwenden können, anstatt mehrere Schleifen auszuführen. Das Problem mit mehreren Schleifen ist

  • sie sind erlaubt problematisch, wenn es um Paginierung geht

  • verursacht unnötige Datenbankabfragen, die die Ladezeiten von Seiten verlangsamen und Ressourcen verschwenden

Eine wichtige Sache, an die Sie sich immer erinnern sollten, ist, dass Sie niemals die Hauptschleife, die Ergebnisse der Hauptabfrage anzeigt, durch eine benutzerdefinierte Abfrage ersetzen dürfen. Sie führen immer zu mehr Problemen als zu deren Lösung. Nehmen Sie sich Zeit und lesen Sie den folgenden Beitrag:

Um Ihr Problem zu beheben, können Sie Ihre pre_get_posts-Aktion und den found_posts-Filter entfernen, da Sie keine Offsets festlegen oder die Paginierung neu berechnen müssen.

Sie müssen Ihre Schleife auf der gewünschten Seite an Ihre Bedürfnisse anpassen

BEISPIEL 1

Gestalte den ersten Beitrag anders und zeige mehr Infos als andere Beiträge

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

            if ( 0 === $wp_query->current_post ) { // Target the first post only
                // Do what you need to do for the first post only
            } else {
                // Display all the other posts as needed   
            }
    }
}

ODER

if ( have_posts() ) {
    // Start our custom counter
    $counter = 0;
    while ( have_posts() ) {
        the_post();

            if ( 0 === $counter ) { // Target the first post only
                // Do what you need to do for the first post only
            } else {
                // Display all the other posts as needed   
            }
        // Update the counter 
       $counter++;
    }
}

Sie können diese Methode auf jedes komplexe Markup anwenden. Sie können benutzerdefinierte Zähler zum Öffnen und Schließen benutzerdefinierter Divs, zum Anwenden unterschiedlicher Stile auf die Post-Position oder sogar zum Erstellen von Post-Gittern festlegen. Ich habe eine ganze Reihe von Beiträgen zu diesem Thema verfasst. Sehen Sie sich also unbedingt meine Antworten an

BEISPIEL 2

Wenn Sie Beiträge anzeigen möchten, die nach Beitragstyp mit den Beitragstypen post und page gruppiert sind. Hier führen wir die Schleife aus, um Posts vom Typ post anzuzeigen, die Schleife zurückzuspulen und erneut auszuführen, aber dieses Mal werden nur Posts vom Typ page angezeigt

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

            if ( 'post' === get_post_type() ) { // Only display posts from post post type
                // Do what you need to do post post type posts
            } 
    }

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

    while ( have_posts() ) {
        the_post();

            if ( 'page' === get_post_type() ) { // Only display posts from page post type
                // Do what you need to do page post type posts
            } 
    }
}

FAZIT

Wie Sie sehen, wird die Notwendigkeit mehrerer Schleifen nicht immer bestätigt, unabhängig davon, wie komplex Sie sich fühlen, es wird immer eine Schleife ausreichen. Wir müssen nur die Schleife PHP verwenden. und filtert geschickt zu unserem Vorteil

2
Pieter Goosen