it-swarm.com.de

Unterschiedliche "posts_per_page" -Einstellung für die erste und die restlichen Seiten?

Wie stellen Sie die Abfrageeinstellung posts_per_page so ein, dass auf der ersten der paginierten Seiten (von Home, Archiv, Suche usw.) und auf den übrigen Seiten eine andere Anzahl von Posts angezeigt wird?

Angenommen, ich möchte 10 Posts auf der ersten der Seiten der Kategoriearchive und 15 auf den übrigen Seiten anzeigen. Wie mache ich es?

Das funktioniert :

function itsme_category_offset( $query ) {
  if( $query->is_category() && $query->is_main_query() ) {

    if( !$query->is_paged() ) {

      $query->set( 'posts_per_page', 10 );

    } else {

      $query->set( 'offset', 10 );
      $query->set( 'posts_per_page', 15 );

    }
  }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

Aber ...

Laut dem Codex-Eintrag für WP_Query() pagination parameters :

offset (int) - Anzahl der zu verschiebenden oder zu übergebenden Pfosten. Warnung: Das Setzen des Offset-Parameters überschreibt/ignoriert den ausgelagerten Parameter und unterbricht die Paginierung

Und laut dem verknüpften Codex-Eintrag für eine Problemumgehung :

Das Angeben von fest codierten Offsets in Abfragen kann und wird die Paginierung unterbrechen, da Offset von WordPress intern zum Berechnen und Behandeln der Paginierung verwendet wird.

Die angegebene Problemumgehung verwendet eine Funktion, die sich in den found_posts-Filter einhakt und den Offset festlegt. Es nimmt an, dass ich so etwas tun sollte:

function itsme_category_offset( $query ) {
  if( $query->is_category() && $query->is_main_query() ) {
    $paged = get_query_var( 'paged' );

    if( 0 == $paged ) {

      $query->set( 'posts_per_page', 10 );

    } else {

      $offset = 10 + ( ($paged - 2) * 15 );
      $query->set( 'offset', $offset );
      $query->set( 'posts_per_page', 15 );

    }
  }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

function itsme_adjust_category_offset_pagination( $found_posts, $query ) {
  $paged = get_query_var( 'paged' );
  if( $query->is_category() && $query->is_main_query() ) {
    if( 0 == $paged ) {

      $offset = 0;

    } else {

      $offset = 10 + ( ($paged - 2) * 15 );

    }

    return $found_posts - $offset;
  }
}
add_filter( 'found_posts', 'itsme_adjust_category_offset_pagination' );

Ist die Codex-Warnung immer noch korrekt, da meine einfachere Funktion bereits funktioniert? (d. h. sollte ich es tun, wie im zweiten Codeblock gezeigt?) Wurde dieses Versatz-/Paginierungsproblem in einer neueren Version von WordPress behoben? Und wenn ja: wie?

6
its_me

Fall 1: Einfacher Versatz

Sie möchten Beiträge eines Kategoriearchivs mit 'n' versetzen, d. H. Sie möchten einfach nicht die ersten/letzten 'n' Beiträge in einem Archiv anzeigen.

Das heißt (unter Berücksichtigung der Einstellung posts_per_page in WP Dashboard> Einstellungen> Lesen auf 10 gesetzt), dass die Einträge 11 bis 20 auf der ersten Seite angezeigt werden sollen (z. B. example.com/category/tech/). 21 bis 30 beim zweiten (zB example.com/category/tech/page/2/), 31 bis 40 beim dritten und so weiter.

Wie auch immer, so würden Sie das machen:

/*
 * Offset posts by 10 on 'Techonology (tech)' category archive
 */
function itsme_category_offset( $query ) {
    $offset = 10;
    $ppp = get_option( 'posts_per_page' );
    $paged = $query->query_vars[ 'paged' ];

    if( $query->is_category( 'tech' ) && $query->is_main_query() ) {
        if( !is_paged() ) {

            $query->set( 'offset', $offset );

        } else {

            $paged_offset = $offset + ( ($paged - 1) * $ppp );
            $query->set( 'offset', $paged_offset );

        }
    }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

Dann gibt es noch eine Sache. Vor dem Erstellen einer Paginierung überprüft WordPress die Gesamtzahl der Beiträge, die die WP_Query -Klasse beim Ausführen einer Abfrage gefunden hat.

Damit die Paginierung ordnungsgemäß funktioniert, müssen Sie die offset aus der Gesamtzahl der von der Abfrage gefundenen Posts entfernen (da die ersten 10 Posts nicht angezeigt werden). Und so würden Sie es machen:

function itsme_adjust_category_offset_pagination( $found_posts, $query ) {
    $offset = 10;

    if( $query->is_category( 'tech' ) && $query->is_main_query() ) {
        return( $found_posts - $offset );
    }
}
add_filter( 'found_posts', 'itsme_adjust_category_offset_pagination', 10, 2 );

Das ist es!

PS: (Eine technische Erklärung finden Sie hier .)


Fall 2: Bedingter Versatz

Wie in meinem Fall möchten Sie die Anzahl der Posts auf der ersten Seite eines Archivs und die Anzahl der Posts auf den anderen Seiten anzeigen.

Das heißt, (unter Berücksichtigung, dass Sie nur 5 Posts auf der ersten Seite des Archivs anzeigen möchten und die restlichen Seiten der Einstellung posts_per_page in WP Dashboard> Einstellungen> Lesenentsprechen. _, auf 10 gesetzt) ​​Sie möchten, dass die Beiträge 1 bis 5 auf der ersten Seite (z. B. example.com/category/tech/), 6 bis 15 auf der zweiten Seite (z. B. example.com/category/tech/page/2/), 16 bis 25 auf der dritten Seite usw. angezeigt werden.

So würden Sie das machen:

/*
 * Show a different no. of posts on the first page, and the rest
 * of the pages of 'Techonology (tech)' category archive
 */
function itsme_category_offset( $query ) {
    $ppp = get_option( 'posts_per_page' );
    $first_page_ppp = 5;
    $paged = $query->query_vars[ 'paged' ];

    if( $query->is_category( 'tech' ) && $query->is_main_query() ) {
        if( !is_paged() ) {

            $query->set( 'posts_per_page', $first_page_ppp );

        } else {

            // Not going to explain the simple math involved here
            $paged_offset = $first_page_ppp + ( ($paged - 2) * $ppp );
            $query->set( 'offset', $paged_offset );

            /*
             * As we are not adding a custom `$query->set( 'posts_per_page', ... );`,
             * the default `posts_per_page` setting from WP Dashboard > Settings > Reading
             * will be applied here.
             */

        }
    }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

Dieser Fall ist komplex. Schauen wir uns zunächst an, wie die Funktion found_posts aussehen sollte:

function itsme_adjust_category_offset_pagination( $found_posts, $query ) {
    $ppp = get_option( 'posts_per_page' );
    $first_page_ppp = 5;

    if( $query->is_category( 'tech' ) && $query->is_main_query() ) {
        if( !is_paged() ) {

            return( $found_posts );

        } else {

            return( $found_posts - ($first_page_ppp - $ppp) );

        }
    }
    return $found_posts;
}
add_filter( 'found_posts', 'itsme_adjust_category_offset_pagination', 10, 2 );

Im Gegensatz zu Fall # 1 werden hier keine Beiträge aus der Gesamtsumme entfernt. wir müssen sie alle zeigen; außer wir wollen ein Set Nr. zeigen. der Beiträge auf der ersten Seite des Kategoriearchivs und eine andere Nr. von Beiträgen auf dem Rest der paginierten Seiten.

Das Problem ist, um die Nr. Zu berechnen. $query (WP_Query) überprüft die Einstellung posts_per_page für die aktuelle Seite. Da wir es für alle anderen Seiten außer der ersten auf '10' setzen, geht $query davon aus, dass es für alle Seiten (einschließlich der vorherigen/nächsten, dh einschließlich der ersten Seite) gleich ist, und beginnt mit der Berechnung der Paginierung darauf bezogen.

Also zum Beispiel auf der 2. Seite (wenn wir die Gesamtzahl der Posts als '20' annehmen), gemäß:

  • $queryPaginierung sollte sein: 10 + 10
  • Aber richtig Paginierung wäre: 5 + 10 + 5 (weil wir in der anfänglichen Funktion pre_get_posts die Paginierung für die erste Seite auf '5' setzen)

Wenn wir also auf der zweiten Seite (oder einer anderen Seite als der ersten), wie in unserem Beispiel, $query glauben lassen müssen, dass die Gesamtzahl No. von Beiträgen ist 25, so dass es eine korrekte Paginierung wie folgt erzeugt ...

5 Beiträge auf der ersten Seite + 10 Beiträge auf der zweiten Seite + 5 Beiträge auf der dritten Seite

... denke, es macht es tatsächlich so:

10 Beiträge auf der ersten Seite + 10 Beiträge auf der zweiten Seite + 5 Beiträge auf der dritten Seite

Und da der found_posts-Filter keinerlei Auswirkung darauf hat, wie viele Beiträge tatsächlich auf einer bestimmten Seite angezeigt werden, haben unsere posts_per_page-Einstellungen ab der ersten Funktion ohne Paginierungsprobleme Vorrang.

Das sollte die Dinge klären. (Und lass es mich wissen, wenn etwas nicht stimmt.)


Um die Frage direkt zu beantworten, müssen Sie also so gut wie immer eine Funktion verwenden, die sich in found_posts filter hook einhakt, um den $query gemäß Ihren benutzerdefinierten Regeln anzupassen und um sicherzustellen, dass die Paginierung nicht durcheinander kommt.

9
its_me

Ich habe nicht genügend Stapelwechselpunkte, um dies zu kommentieren, aber ich habe eine Korrektur.

Fall 1: Simple Offset hat auf meiner Website sehr gut funktioniert. Es ist nur eine Korrektur erforderlich, damit der Standardoffset zurückgegeben wird, wenn die spezielle Bedingung nicht erfüllt ist:

function itsme_adjust_category_offset_pagination( $found_posts, $query ) {
    $offset = 10;

    if( $query->is_category( 'tech' ) && $query->is_main_query() ) {
        return( $found_posts - $offset );
    } else {
        return $found_posts;
    }
}
add_filter( 'found_posts', 'itsme_adjust_category_offset_pagination', 10, 2 );
1
Oxfordian3