Dies ist eine ziemlich interessante Frage ( die ich speziell für Ihren Ansatz und Ihre Forschung positiv bewertet habe ). Der große Curveball hier ist die erste Seite der Abfrage:
Sie können die Abfrage nicht so einstellen, dass 0
Beiträge auf der ersten Seite zurückgegeben werden
Wenn 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 von Posts enthält, sodass die $max_num_pages
Eigenschaft immer noch dieselbe bleibt
Wir müssen die WP_Query
Klasse irgendwie " austricksen " , um unsere Beiträge korrekt mit dem Versatz einer Seite zurückzugeben und auch die richtige Anzahl von Seiten zu erhalten, um die letzte Seite in der Abfrage nicht zu verlieren
Schauen wir uns die folgende Idee an und versuchen wir, alles in Code zu setzen. Bevor wir dies tun, möchte ich hier jedoch einige Anmerkungen machen
WICHTIGE NOTIZEN:
Alles ist ungetestet, daher könnte es fehlerhaft sein. Stellen Sie sicher, dass Sie dies lokal mit aktiviertem Debug testen
Der Code erfordert mindestens PHP 5.3. Jede Version unter 5.3 verursacht einen schwerwiegenden Fehler. Hinweis: Wenn Sie noch eine Version unter PHP 5.5 verwenden, sollten Sie bereits vor langer Zeit ein Upgrade durchgeführt haben
Ändern und missbrauchen Sie den Code nach Ihren Wünschen
DIE GLÜHBIRNEN-IDEE:
WAS WIR BRAUCHEN
Damit alles funktioniert, benötigen wir Folgendes:
Die aktuell angezeigte Seitenzahl
Die in den posts_per_page
Leseeinstellungen festgelegte Option
Benutzerdefiniert offset
Ändern Sie die $found_posts
Eigenschaft der Abfrage, um die $max_num_pages
Eigenschaft zu korrigieren
Die Paginierung besteht WP_Query
aus sehr einfachen Codezeilen
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 im Grunde 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 gibt die Anzahl der Beiträge an, die in der generierten SQL-Abfrage übersprungen werden sollen.
Aus Ihrer Frage geht hervor , dass die Offset-Abfrage anscheinend beim Setzen offset
auf 0
fehlschlägt, was seltsam ist, da die folgende Prüfung true 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, verwenden wir dieselbe Logik, um unseren Offset zu berechnen und festzulegen, um Post 1 auf Seite 2 zu erhalten und von dort aus die Abfrage zu paginieren. Für die erste Seite werden wir nichts ändern, sodass die Beiträge, von denen angenommen wird, dass sie sich auf Seite 1 befinden, weiterhin wie gewohnt auf der Seite sind. Wir müssten sie später nur "ausblenden", 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 dieselben Beiträge von Seite 1 auf Seite 2 sehen. Wie bereits erwähnt, wird in diesem Fall entweder is_numeric( 0 )
false zurückgegeben ( was nicht der Fall sein sollte ) oder Sie haben eine andere pre_get_posts
Aktion, die ebenfalls versucht, einen Offset festzulegen, oder Sie verwenden 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 Paginierung, da Sie, wie bereits erwähnt, nur eine kurze Seite haben. Dazu müssen wir den Wert von get_option( 'posts_per_page' )
zur Anzahl der in der Abfrage gefundenen Beiträge hinzufügen, da wir die Abfrage um diesen Betrag versetzen. Auf diese Weise erweitern wir 1
die $max_num_pages
Immobilie effektiv .
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 ZUSAMMEN ( und speziell für @ialocin - Yellow Submarine )
Das sollte alles gehen functions.php
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 einige Optionen:
OPTION 1
Ich würde mich höchstwahrscheinlich für diese Option entscheiden. Was Sie hier tun möchten, ist ein category-news.php
( falls Sie dies noch nicht getan haben ) zu erstellen . Dies ist die Vorlage, die verwendet wird, wenn die news
Kategorie 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 Vorlagenteile news-special.php
und news-loop.php
. Die Grundlagen der beiden benutzerdefinierten Vorlagen sind nun:
news-special.php
-> Dieser Vorlagenteil ist alles, was Sie auf der ersten Seite anzeigen möchten. Fügen Sie hier alle Ihre benutzerdefinierten statischen Informationen hinzu. Achten Sie darauf, die Schleife in dieser Vorlage nicht aufzurufen, da hierdurch die Beiträge der ersten Seite angezeigt werden.
news-loop.php
-> Dies ist die Vorlage, in der wir die Schleife aufrufen. 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
Kategorie 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 innerhalb der Vorlagenhierarchie kollidiert
Ich hoffe das ist nützlich. Fühlen Sie sich frei, Kommentare mit Bedenken zu hinterlassen
BEARBEITEN
Dank des OP gibt es einen bestimmten Fehler in der WP_Query
Klasse. Überprüfen Sie das Trac-Ticket Nr. 34060 . Der Code, den ich gepostet habe, stammt aus Wordpress v4.4 und der Fehler wurde in dieser Version behoben.
Ich bin zum Quellcode von Version 4.3 zurückgekehrt, wo der Fehler liegt, und ich kann bestätigen, dass dieser 0
ignoriert wird, wenn er als Wert festgelegt wird, offset
da der Code einfach prüft, ob der offset
Parameter ist empty
. 0
wird in PHP als leer genommen. Ich bin nicht sicher, ob dieses Verhalten (Fehler) nur in Version 4.3 oder in allen vorherigen Versionen gefunden wurde (laut Ticket ist dieser Fehler in Version 4.3), aber es gibt einen Patch für diesen Fehler, den Sie überprüfen können draußen im Trac-Ticket. Wie gesagt, dieser Fehler wurde definitiv in Version 4.4 behoben
return $found_posts;
nach der if-Anweisung in der Aktion found_posts. Vielen Dank!