Saya membaca @ nacin's. Anda tidak tahu Query kemarin dan diturunkan sedikit lubang kelinci. Sebelum kemarin, saya (keliru) menggunakan query_posts()
untuk semua kebutuhan permintaan saya. Sekarang saya sedikit lebih bijaksana tentang penggunaan WP_Query()
, tetapi masih memiliki beberapa daerah abu-abu.
Apa yang saya pikir saya tahu pasti:
Jika saya membuat loop tambahan di mana saja pada halaman — di sidebar, di footer, segala jenis "posting terkait", dll — saya ingin menggunakan WP_Query()
. Saya bisa menggunakannya berulang kali pada satu halaman tanpa membahayakan. (Baik?).
Apa yang saya tidak tahu pasti
- Kapan saya menggunakan @ nacin ini
pre_get_posts
vsWP_Query()
? Haruskah saya gunakanpre_get_posts
untuk semuanya sekarang? - Ketika saya ingin memodifikasi loop di halaman templat - katakanlah saya ingin memodifikasi halaman arsip taksonomi - apakah saya menghapus
if have_posts : while have_posts : the_post
bagian dan menulis sendiriWP_Query()
? Atau apakah saya memodifikasi output menggunakanpre_get_posts
file functions.php saya?
tl; dr
Aturan dr yang ingin saya tarik dari ini adalah:
- Jangan pernah gunakan
query_posts
lagi - Saat menjalankan beberapa kueri pada satu halaman, gunakan
WP_Query()
- Saat memodifikasi sebuah loop, lakukan ini __________________.
Terima kasih atas kebijaksanaannya
Terry
ps: Saya telah melihat dan membaca: Kapan Anda harus menggunakan WP_Query vs query_posts () vs get_posts ()? Yang menambahkan dimensi lain - get_posts
. Tetapi tidak berurusan pre_get_posts
sama sekali.
sumber
Jawaban:
Anda benar untuk mengatakan:
pre_get_posts
pre_get_posts
adalah filter, untuk mengubah kueri apa pun . Ini paling sering digunakan untuk mengubah hanya 'permintaan utama':(Saya juga akan memeriksa yang
is_admin()
mengembalikan false - meskipun ini mungkin berlebihan.) Permintaan utama muncul di template Anda sebagai:Jika Anda pernah merasa perlu mengedit loop ini - gunakan
pre_get_posts
. yaitu Jika Anda tergoda untuk menggunakanquery_posts()
- gunakanpre_get_posts
saja.WP_Query
Permintaan utama adalah contoh penting dari a
WP_Query object
. WordPress menggunakannya untuk memutuskan template mana yang akan digunakan, misalnya, dan argumen apa pun yang diteruskan ke url (misalnya pagination) semuanya disalurkan ke instanceWP_Query
objek tersebut.Untuk loop sekunder (misalnya di bilah samping, atau daftar 'posting terkait'), Anda ingin membuat instance
WP_Query
objek Anda sendiri yang terpisah . MisalnyaPerhatikan
wp_reset_postdata();
- ini karena loop sekunder akan menimpa$post
variabel global yang mengidentifikasi 'posting saat ini'. Ini pada dasarnya mengatur ulang bahwa untuk$post
kita berada.get_posts ()
Ini pada dasarnya adalah pembungkus untuk instance
WP_Query
objek yang terpisah. Ini mengembalikan array objek posting. Metode yang digunakan dalam loop di atas tidak lagi tersedia untuk Anda. Ini bukan 'Loop', hanya sebuah array objek posting.Menanggapi pertanyaan Anda
pre_get_posts
untuk mengubah kueri utama Anda. GunakanWP_Query
objek terpisah (metode 2) untuk loop sekunder di halaman templat.pre_get_posts
.sumber
get_posts()
ini lebih efisien.get_posts()
untuk permintaan utama - itu untuk permintaan sekunder.Ada dua konteks yang berbeda untuk loop:
Masalahnya
query_posts()
adalah loop sekunder yang mencoba menjadi yang utama dan gagal total. Jadi, lupakan saja.Untuk memodifikasi loop utama
query_posts()
pre_get_posts
filter dengan$query->is_main_query()
cekrequest
filter (sedikit terlalu kasar sehingga di atas lebih baik)Untuk menjalankan loop sekunder
Gunakan
new WP_Query
atauget_posts()
yang cukup banyak dipertukarkan (yang terakhir adalah pembungkus tipis untuk yang pertama).Membersihkan
Gunakan
wp_reset_query()
jika Anda menggunakanquery_posts()
atau mengacaukan global$wp_query
secara langsung - sehingga Anda hampir tidak perlu melakukannya.Gunakan
wp_reset_postdata()
jika Anda menggunakanthe_post()
atausetup_postdata()
atau mengacaukan global$post
dan perlu mengembalikan keadaan awal hal-hal terkait pasca.sumber
wp_reset_postdata()
Ada skenario yang sah untuk digunakan
query_posts($query)
, misalnya:Anda ingin menampilkan daftar posting atau posting jenis posting khusus pada halaman (menggunakan templat halaman)
Anda ingin membuat pagination dari posting tersebut berfungsi
Sekarang mengapa Anda ingin menampilkannya di halaman alih-alih menggunakan templat arsip?
Ini lebih intuitif untuk administrator (pelanggan Anda?) - mereka dapat melihat halaman di 'Halaman'
Lebih baik menambahkannya ke menu (tanpa halaman, mereka harus menambahkan url secara langsung)
Jika Anda ingin menampilkan konten tambahan (teks, thumbnail pos, atau konten meta khusus) pada templat, Anda dapat dengan mudah mendapatkannya dari halaman (dan semuanya juga lebih masuk akal bagi pelanggan). Lihat apakah Anda menggunakan templat arsip, Anda harus melakukan hardcode pada konten tambahan atau menggunakan misalnya opsi tema / plugin (yang membuatnya kurang intuitif untuk pelanggan)
Berikut ini contoh kode yang disederhanakan (yang akan ada di templat halaman Anda - mis. Halaman-halaman-posts.php):
Sekarang, untuk menjadi sangat jelas, kita bisa menghindari menggunakan di
query_posts()
sini juga dan menggunakannyaWP_Query
- seperti:Tapi, mengapa kita melakukan itu ketika kita memiliki fungsi kecil yang bagus tersedia untuk itu?
sumber
Saya memodifikasi permintaan WordPress dari functions.php:
sumber
Hanya untuk menguraikan beberapa perbaikan pada jawaban yang diterima sejak WordPress berevolusi dari waktu ke waktu dan beberapa hal berbeda sekarang (lima tahun kemudian):
Sebenarnya adalah hook tindakan. Bukan filter, dan itu akan memengaruhi kueri apa pun.
Sebenarnya ini juga tidak benar. Fungsi ini
have_posts
mengulangiglobal $wp_query
objek yang tidak terkait hanya dengan permintaan utama.global $wp_query;
dapat diubah dengan kueri sekunder juga.Sebenarnya, saat ini
WP_Query
adalah kelas, jadi kami memiliki instance dari kelas.Untuk menyimpulkan: Pada saat @StephenHarris menulis kemungkinan besar semua ini benar, tetapi seiring waktu hal-hal di WordPress telah berubah.
sumber
get_posts
mengembalikan array objek posting, bukanWP_Query
objek, sehingga memang masih benar. danWP_Query
selalu menjadi kelas, instance dari kelas = objek.