Wie kann ich eine Kategorie-Zielseite erstellen, auf die Seiten mit Beiträgen folgen?

Ich versuche, eine Kategorievorlage in meinem Thema zu erstellen, die statischen Inhalt anzeigt, wenn sich der Benutzer auf der ersten Seite des Archivs befindet, und dann die Beiträge in der Kategorie auf den folgenden Seiten anzeigt. Ich versuche im Grunde, das Verhalten der Kategorie auf Wired.com nachzubilden, wo http://www.wired.com/category/design eine Zielseite ist, während / category / design / page / 1 eine umgekehrte chronologische Auflistung von Beiträgen wie Ihnen zeigt würde auf einem Kategoriearchiv erwarten.

Der Schlüssel hier ist, dass ich keine Beiträge aus der Kategorie Archiv auf der ersten Seite zeige, also brauche ich die nächste Seite, um mit dem ersten Post zu beginnen. Ich habe zuerst versucht, dies mit offset und manueller Paginierung zu tun, indem ich den Offset der Abfrage auf 0 setze, wenn die ‘paged’ Abfrage var 2 ist. Aber Offset wird ignoriert, wenn es auf Null gesetzt ist, also kann ich den Offset auf setzen 1 und starte mit dem zweiten Beitrag in der Kategorie.

Das habe ich zu functions.php hinzugefügt:

add_action('pre_get_posts', 'category_query_offset', 1 ); function category_query_offset(&$query) { // Before anything else, make sure this is the right query if (!$query->is_category('news')) { return; } // Next, determine how many posts per page $ppp = get_option('posts_per_page'); //Next, detect and handle pagination if ($query->is_paged) { // Manually determine page query offset $page_offset = (($query->query_vars['paged']-1) * $ppp) - $ppp; // Apply adjust page offset $query->set('offset', $page_offset ); } } 

Was wäre besser, und was es wie Wired aussieht, ist, die Standardpaginierung zu verwenden, damit die Beiträge auf Seite 1 beginnen, aber eine Seite 0 für den statischen Inhalt einfügen. Hypothetisch scheint dies möglich zu sein, indem man den statischen Inhalt anzeigt, wenn ‘paged’ 0 ist, und die erste Seite von Beiträgen anzeigt, wenn ‘paged’ 1 ist. Das Problem ist, dass ‘paged’ nie 1 ist, weil WordPress ‘paged’ setzt ‘auf Null, wenn der Benutzer die erste Seite anfordert. Das heißt, ‘paged’ ist 0 für beide / category / news / page / 1 und / category / news.

Gibt es eine Möglichkeit zu überprüfen, ob der Benutzer / category / news / page / 1 im Gegensatz zu / category / news angefordert hat? Ist es möglich, alle Beiträge in der Kategorie ab Seite 2 anzuzeigen?

Solutions Collecting From Web of "Wie kann ich eine Kategorie-Zielseite erstellen, auf die Seiten mit Beiträgen folgen?"

Das ist eine ziemlich interessante Frage ( die ich speziell für Ihre Herangehensweise und Ihre Forschung aufgestockt habe ). Der große Curveball ist hier die erste Seite der Abfrage:

  • Sie können die Abfrage nicht so einstellen, dass auf der ersten Seite 0 Beiträge zurückgegeben werden

  • Indem Sie den Seiteninhalt jeder Seite um eine Seite nach oben verschieben, verlieren Sie die letzte Seite, da die Abfrage immer noch nur die gleiche Anzahl an Posts enthält, so dass die Eigenschaft $max_num_pages weiterhin gleich bleibt

Wir müssen die WP_Query class irgendwie “tricksen”, um unsere Posts korrekt mit dem Offset einer Seite zurückzugeben, und auch die korrekte Anzahl an Seiten, um nicht die letzte Seite in der Abfrage zu verlieren

Lass uns die folgende Idee betrachten und versuchen, alles in Code zu schreiben. Bevor wir das tun, möchte ich hier jedoch einige Anmerkungen machen

WICHTIGE NOTIZEN:

  • Alles ist ungetestet, also könnte es errorshaft sein. Stellen Sie sicher, dass Sie dies lokal mit aktiviertem Debug testen

  • Der Code erfordert mindestens PHP 5.3, jede Version unter 5.3 führt zu einem schwerwiegenden Fehler. Beachten Sie, wenn Sie immer noch eine Version unter PHP 5.5 verwenden, sollten Sie bereits vor längerer Zeit aktualisiert haben

  • Ändern und missbrauchen Sie den Code so, wie Sie es für richtig halten

DIE GLÜHBIRNE IDEE:

Was wir brauchen

Damit alles funktioniert, benötigen wir Folgendes:

  • Die aktuelle Seitennummer wird angezeigt

  • Die Option posts_per_page in den posts_per_page festgelegt

  • Benutzerdefinierter offset

  • $found_posts Eigenschaft $found_posts der Abfrage, um die Eigenschaft $max_num_pages zu korrigieren

Paginierung ist WP_Query kommt eine sehr einfache paar Zeilen Code

 if ( empty($q['nopaging']) && !$this->is_singular ) { $page = absint($q['paged']); if ( !$page ) $page = 1; // If 'offset' is provided, it takes precedence over 'paged'. if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) { $q['offset'] = absint( $q['offset'] ); $pgstrt = $q['offset'] . ', '; } else { $pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', '; } $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page']; } 

Was grundsätzlich passiert, sobald ein Offset explizit gesetzt ist, wird der paged Parameter ignoriert. Der erste Parameter der SQL- LIMIT Klausel wird aus dem Offset neu berechnet und ist die Anzahl der Posts, die in der generierten SQL-Abfrage übersprungen werden.

Wenn Sie offset auf 0 , schlägt die Offset-Abfrage offensichtlich fehl, was seltsam ist, da die folgende Überprüfung wahr zurückgeben sollte

 if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) 

0 ist eine gültige Zahl und sollte True zurückgeben. Wenn dies bei Ihrer Installation nicht der Fall ist, sollten Sie das Problem beheben

Um auf das vorliegende Problem zurückzukommen, werden wir die gleiche Art von Logik verwenden, um unseren Offset zu berechnen und zu setzen, um Post 1 auf Seite 2 zu erhalten und von dort die Abfrage zu paginieren. Für die erste Seite werden wir nichts ändern, so dass die Posts, die auf Seite 1 sein sollen, immer noch auf der Seite sind, wir müssten sie später nur “verstecken”, damit wir sie nicht auf der Seite anzeigen 1

 add_action( 'pre_get_posts', function ( $q ) { if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT && $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT && $q->is_cateory( 'news' ) // Only target the news category ) { $current_page = $q->get( 'paged' ); // Get the current page number // We will only need to run this from page 2 onwards if ( $current_page != 0 ) { // You can also use if ( is_paged() ) { // Get the amount of posts per page $posts_per_page = get_option( 'posts_per_page' ); // Recalculate our offset $offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0 // Set our offset $q->set( 'offset', $offset ); } } }); 

Sie sollten die gleichen Beiträge von Seite 1 auf Seite 2 sehen. Wenn dies nicht der Fall ist, gibt entweder is_numeric( 0 ) false zurück ( was nicht sein sollte ) oder Sie haben eine andere pre_get_posts Aktion, die ebenfalls versucht Setzen Sie einen Offset oder verwenden Sie die posts_* -Klauselfilter ( genauer gesagt den post_limits Filter ). Dies wäre etwas, das Sie selbst debuggen müssten.

Das nächste Problem ist die Korrektur der Seitennummerierung, weil Sie, wie ich bereits erwähnt habe, eine kurze Seite haben werden. Dazu müssen wir den Wert von get_option( 'posts_per_page' ) der Anzahl der in der Abfrage gefundenen Posts get_option( 'posts_per_page' ) da wir die Abfrage um diesen Betrag get_option( 'posts_per_page' ) . Auf diese Weise fügen wir der Eigenschaft $max_num_pages effektiv 1 $max_num_pages .

 add_action( 'found_posts', function ( $found_posts, $q ) { if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT && $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT && $q->is_cateory( 'news' ) // Only target the news category ) { $found_posts = $found_posts + get_option( 'posts_per_page'); } }, 10, 2 ); 

Dies sollte alles außer der ersten Seite sortieren.

JETZT ALLE ZUSAMMEN ( und speziell für @ialocin – Yellow Submarine )

Dies sollte alles in functions.php gehen

 add_action( 'pre_get_posts', function ( $q ) { if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT && $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT && $q->is_cateory( 'news' ) // Only target the news category ) { $current_page = $q->get( 'paged' ); // Get the current page number // We will only need to run this from page 2 onwards if ( $current_page != 0 ) { // You can also use if ( is_paged() ) { // Get the amount of posts per page $posts_per_page = get_option( 'posts_per_page' ); // Recalculate our offset $offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0 // Set our offset $q->set( 'offset', $offset ); } } }); add_filter( 'found_posts', function ( $found_posts, $q ) { if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT && $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT && $q->is_cateory( 'news' ) // Only target the news category ) { $found_posts = $found_posts + get_option( 'posts_per_page'); } return $found_posts; }, 10, 2 ); 

Optionen der ersten Seite

Hier gibt es ein paar Optionen:

OPTION 1

Ich würde höchstwahrscheinlich für diese Option gehen. Was Sie hier tun möchten, ist eine category-news.php zu erstellen ( wenn Sie dies noch nicht getan haben ). Dies ist die Vorlage, die immer dann verwendet wird, wenn die news angezeigt wird. Diese Vorlage wird sehr einfach sein

Beispiel

 < ?php get_header() if ( !is_paged() ) { // This is the first page get_template_part( 'news', 'special' ); } else { // This is not the first page get_template_part( 'news', 'loop' ); } get_sidebar(); get_footer(); 

Wie Sie sehen können, habe ich zwei Template-Teile, news-special.php und news-loop.php . Nun sind die Grundlagen der beiden benutzerdefinierten Vorlagen:

  • news-special.php -> Dieser Schablonenteil ist das, was Sie auf der ersten Seite anzeigen möchten. Fügen Sie alle Ihre benutzerdefinierten statischen Informationen hier hinzu. Achten Sie darauf, die Schleife in dieser Vorlage nicht aufzurufen, da sonst die Posts der ersten Seite angezeigt werden.

  • news-loop.php -> Dies ist die Vorlage, wo wir die Schleife aufrufen werden. Dieser Abschnitt sieht ungefähr so ​​aus:

     global $wp_query; while ( have_posts() ) { the_post(); // Your template tags and markup } 

OPTION 2

Erstellen Sie eine separate Vorlage mit Ihrem statischen Inhalt und verwenden Sie einfach den category_template Filter, um diese Vorlage zu verwenden, wenn wir die erste Seite der news anzeigen. Stellen Sie außerdem sicher, dass Sie die Standardschleife in dieser Vorlage nicht aufrufen. Stellen Sie außerdem sicher, dass Ihre Namenskonvention hier nicht mit Vorlagennamen in der Vorlagenhierarchie kollidiert

Ich hoffe, das ist nützlich. Fühlen Sie sich frei, Kommentare mit Bedenken zu tolerieren

BEARBEITEN

Dank des OP gibt es einen bestimmten Fehler in der WP_Query class, überprüfen Sie das Trac-Ticket # 34060 . Der Code, den ich gepostet habe, stammt aus WordPress v4.4 und der Bug ist in dieser Version behoben.

Ich ging zurück zum Quellcode von v4.3, wo der Fehler ist, und ich kann bestätigen, dass 0 ignoriert wird, wenn es als Offsetwert eingestellt ist, da der Code einfach überprüft, ob der offset Parameter empty . 0 wird in PHP als leer angesehen. Ich bin nicht sicher, ob dieses Verhalten (Bug) nur in v4.3 oder in allen vorherigen Versionen gefunden wird (je nach Ticket ist dieser Fehler in v4.3), aber es gibt einen Patch für diesen Fehler, den Sie überprüfen können draußen im Trac-Ticket. Wie ich schon sagte, dieser Fehler wurde definitiv in v4.4 behoben

Aktualisieren:

 add_action('pre_get_posts', 'category_query_offset', 1 ); function category_query_offset($query) { // Before anything else, make sure this is the right query if (!$query->is_category('news')) { return; } // Next, determine paged $ppp = get_option('paged'); } // Next, handle paged if($ppp > 1){ $query->set('paged', $ppp-1); } 

Versuchen Sie etwas wie

 $paged = ( get_query_var('paged') ) ? get_query_var('paged')-1 : 1; $args = array ( 'paged' => $paged, );