Ini adalah pertanyaan yang cukup menarik ( yang telah saya angkat, khususnya untuk pendekatan dan penelitian Anda ). Curveball besar di sini adalah halaman pertama dari kueri:
Anda tidak dapat mengatur kueri untuk mengembalikan 0
posting di halaman pertama
Dengan memindahkan konten halaman dari setiap halaman ke atas oleh satu halaman, Anda akan kehilangan halaman terakhir karena kueri masih akan memiliki jumlah posting yang sama sehingga $max_num_pages
properti akan tetap sama.
Kita perlu "menipu" WP_Query
kelas untuk mengembalikan postingan kita dengan benar dengan offset satu halaman, dan juga mendapatkan jumlah halaman yang benar agar tidak kehilangan halaman terakhir dalam kueri
Mari kita lihat ide berikut dan mencoba untuk memasukkan semuanya ke dalam kode. Sebelum kita melakukannya, saya ingin membuat beberapa catatan di sini
CATATAN PENTING:
Semuanya belum teruji, jadi mungkin buggy. Pastikan untuk menguji ini secara lokal dengan debug dihidupkan
Kode membutuhkan setidaknya PHP 5.3, versi di bawah 5.3 akan menyebabkan kesalahan fatal. Catatan, jika masih menggunakan versi apa pun di bawah PHP 5.5, Anda seharusnya sudah meningkatkan versi lama
Ubah dan penyalahgunaan kode sesuai keinginan Anda
IDE LIGHTBULB:
APA YANG KAMI BUTUHKAN
Untuk membuat semuanya berfungsi, kita perlu yang berikut:
Nomor halaman saat ini sedang dilihat
The posts_per_page
set pilihan dalam pengaturan membaca
Adat offset
Ubah $found_posts
properti kueri untuk memperbaiki $max_num_pages
properti
Pagination WP_Query
diturunkan beberapa baris kode yang sangat sederhana
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'];
}
Apa yang pada dasarnya terjadi, setelah offset diatur secara eksplisit, paged
parameter diabaikan. Parameter pertama LIMIT
klausa SQL dihitung ulang dari offset dan akan menjadi jumlah posting yang dilewati dalam query SQL yang dihasilkan.
Dari pertanyaan Anda, tampaknya saat menyetel offset
ke 0
, kueri offset gagal, yang aneh, karena pemeriksaan berikut akan mengembalikan true
if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) )
0
adalah angka yang valid dan harus mengembalikan true. Jika ini tidak pada instalasi Anda, Anda harus men-debug masalah tersebut
Untuk kembali ke masalah yang ada, kami akan menggunakan jenis logika yang sama untuk menghitung dan mengatur offset kami untuk mendapatkan pos 1 di halaman 2 dan dari sana paginate permintaan. Untuk halaman pertama, kami tidak akan mengubah apa pun, sehingga postingan yang seharusnya berada di halaman 1 masih akan di halaman seperti biasa, kami hanya perlu "menyembunyikan" mereka nanti sehingga kami tidak menampilkannya di halaman 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 );
}
}
});
Anda harus melihat posting yang sama dari halaman 1 di halaman 2. Seperti yang saya katakan sebelumnya, jika ini tidak terjadi, salah satu is_numeric( 0 )
akan kembali salah ( yang seharusnya tidak ) atau Anda memiliki pre_get_posts
tindakan lain yang juga mencoba untuk mengatur offset atau Anda menggunakan penggunaan posts_*
filter klausa ( lebih khusus, post_limits
filter ). Ini akan menjadi sesuatu yang perlu Anda debug sendiri.
Masalah berikutnya adalah memperbaiki pagination, karena seperti yang saya katakan sebelumnya, Anda akan kekurangan halaman. Untuk ini, kita perlu menambahkan nilai get_option( 'posts_per_page' )
ke jumlah posting yang ditemukan dalam permintaan karena kita mengimbangi permintaan dengan jumlah itu. dengan melakukan hal ini, kita secara efektif menambahkan 1
ke $max_num_pages
properti.
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 );
Ini harus mengurutkan semuanya, kecuali halaman pertama.
SEMUA BERSAMA SEKARANG ( dan khusus untuk @ialocin - Kapal Selam Kuning )
Ini semua harus masuk 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 );
OPSI HALAMAN PERTAMA
Ada beberapa opsi di sini:
PILIHAN 1
Saya kemungkinan besar akan memilih opsi ini. Apa yang ingin Anda lakukan di sini adalah membuat category-news.php
( jika Anda belum melakukan ini ). Ini akan menjadi templat yang akan digunakan setiap kali news
kategori dilihat. Template ini akan sangat sederhana
Contoh
<?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();
Seperti yang Anda lihat, saya telah menyertakan dua bagian templat, news-special.php
dan news-loop.php
. Sekarang, dasar-dasar kedua templat khusus adalah:
news-special.php
-> Bagian templat ini akan menjadi apa pun yang ingin Anda tampilkan di halaman pertama. Tambahkan semua info statis khusus Anda di sini. Berhati-hatilah untuk tidak memanggil loop dalam template ini karena ini akan menampilkan posting dari halaman pertama.
news-loop.php
-> Ini adalah templat di mana kita akan mengaktifkan perulangan. Bagian ini akan terlihat seperti ini:
global $wp_query;
while ( have_posts() ) {
the_post();
// Your template tags and markup
}
PILIHAN 2
Buat templat terpisah dengan konten statis Anda dan cukup gunakan category_template
filter untuk menggunakan templat ini ketika kami melihat halaman pertama dari news
kategori tersebut. Juga, pastikan untuk tidak mengaktifkan loop default di template ini. Juga, pastikan bahwa konvensi penamaan Anda di sini tidak bertabrakan dengan nama templat di dalam hierarki templat
Saya harap ini bermanfaat. Jangan ragu untuk meninggalkan komentar dengan keprihatinan
EDIT
Berkat OP, ada bug yang pasti di WP_Query
kelas, periksa tiket trac # 34060 . Kode yang saya posting adalah dari Wordpress v4.4, dan bug diperbaiki pada versi ini.
Saya kembali ke kode sumber v4.3, di mana bug itu berada, dan saya dapat mengonfirmasi bahwa 0
diabaikan ketika ditetapkan sebagai nilai offset
karena kode hanya memeriksa apakah offset
parameternya empty
. 0
diambil sebagai kosong di PHP. Saya tidak yakin apakah perilaku ini (bug) hanya ditemukan di v4.3 saja atau di semua versi sebelumnya (sesuai tiket, bug ini ada di v4.3), tetapi ada tambalan untuk bug ini yang dapat Anda periksa di tiket trac. Seperti yang saya katakan, bug ini sudah pasti diperbaiki di v4.4
return $found_posts;
setelah pernyataan if dalam tindakan found_posts. Terima kasih!