olvastam @nacin “s Nem ismeri a lekérdezést tegnap, és egy kis lekérdező nyúllyukba küldtek. Tegnap előtt (tévesen) a query_posts()
szolgáltatást használtam minden lekérdezési igényemhez. Most “kicsit bölcsebb vagyok a WP_Query()
használatában, de van néhány szürke területem.
Amit szerintem biztosan tudok:
Ha további hurkol az oldalon bárhol – az oldalsávon, a láblécben, bármilyen “kapcsolódó bejegyzés” stb. – A következőt szeretném használni: WP_Query()
. Ezt többször használhatom egyetlen oldalon, anélkül, hogy kárt okoznék. (jobb?).
Amit nem tudok biztosan
- mikor @nacin “s
pre_get_posts
vs.WP_Query()
? Használjam most apre_get_posts
alkalmazást? - Ha módosítani akarom a sablonoldal ciklusát – mondjuk azt, hogy módosítani szeretnék egy taxonómiaarchívum oldalt -, akkor távolítsam el a
if have_posts : while have_posts : the_post
részt, és írjam meg sajátWP_Query()
? Vagy módosíthatom a kimenetet apre_get_posts
segítségével a functions.php fájlomban?
tl; dr
A tl; dr szabályok Ebből szeretnék levonni a következőket:
- Soha ne használja a
query_posts
már - Ha több lekérdezést futtat egyetlen oldalon, használja a következőt:
WP_Query()
- A ciklus módosításakor tegye ezt __________________.
Köszönöm a bölcsességet
Terry
ps: Láttam és olvastam: Mikor kell használni a WP_Query vs query_posts () vs get_posts ()? Ez egy másik dimenziót ad hozzá – get_posts
. De egyáltalán nem foglalkozik a pre_get_posts
.
Megjegyzések
- A (z) lehetséges másolata. Mikor érdemes használni a WP_Query vs query_posts () vs get_posts ( )?
- @saltcod, most más a helyzet, a WordPress fejlődött, néhány megjegyzést fűztem az elfogadott válaszhoz képest itt .
Válasz
Igazad van, ha ezt mondod:
Soha ne használja a
query_posts
szót
pre_get_posts
pre_get_posts
egy szűrő, a bármely lekérdezés. Leggyakrabban csak a “fő lekérdezés” megváltoztatására használják:
add_action("pre_get_posts","wpse50761_alter_query"); function wpse50761_alter_query($query){ if( $query->is_main_query() ){ //Do something to main query } }
(azt is ellenőrizném, hogy is_admin()
visszaadja a false értéket – bár ez felesleges lehet.). A fő lekérdezés a sablonokban a következő néven jelenik meg:
if( have_posts() ): while( have_posts() ): the_post(); //The loop endwhile; endif;
Ha bármikor szükségét érzi ennek a ciklusnak a szerkesztésére, használja a div>. azaz ha a query_posts()
használatára készteti – használja helyette a pre_get_posts
szót.
WP_Query
A fő lekérdezés a WP_Query object
fontos példánya. A WordPress arra használja, hogy eldöntse például, melyik sablont használja, és az url-be továbbított argumentumok (pl. Oldalszámozás) mind a WP_Query
objektum azon példányába kerülnek.
Másodlagos ciklusok esetén (pl. oldalsávokban vagy “kapcsolódó bejegyzések” listákban) létre kell hoznia saját külön példányát a WP_Query
objektumból. Pl.
$my_secondary_loop = new WP_Query(...); if( $my_secondary_loop->have_posts() ): while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post(); //The secondary loop endwhile; endif; wp_reset_postdata();
Figyelem wp_reset_postdata();
– ez azért van, mert a másodlagos hurok felülírja a globális $post
változó, amely azonosítja az “aktuális bejegyzést”. Ez lényegében visszaállítja azt az $post
elemre, amin éppen vagyunk.
get_posts ()
Ez lényegében egy burkoló egy WP_Query
objektum külön példányának. Ez egy tömb postobjektumot ad vissza. A fenti ciklusban használt módszerek már nem állnak rendelkezésére. Ez nem ” ta “Loop”, egyszerűen egy sor post objektum.
<ul> <?php global $post; $args = array( "numberposts" => 5, "offset"=> 1, "category" => 1 ); $myposts = get_posts( $args ); foreach( $myposts as $post ) : setup_postdata($post); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li> <?php endforeach; wp_reset_postdata(); ?> </ul>
Válaszul a kérdéseire
- A
pre_get_posts
segítségével módosíthatja a fő lekérdezést. Használjon különWP_Query
objektumot (2. módszer) a sablonoldalak másodlagos hurkjaihoz. - Ha módosítani szeretné a fő hurok lekérdezését, használja a
pre_get_posts
.
Megjegyzések
- Tehát van-e olyan forgatókönyv, amikor az ember a WP_Query helyett a get_posts () címre menne?
- @drtanz – igen. Tegyük fel, hogy például nem kell ldalaz oldalszámozás vagy ragacsos bejegyzések a tetején – ezekben az esetekben a
get_posts()
hatékonyabb. - De nem adna ‘ t egy olyan kiegészítő lekérdezést, amelynél csak a pre_get_posts-t módosíthatnánk a fő lekérdezés módosításához?
- @drtanz – nem akarna ‘ ne használja a
get_posts()
-t a fő lekérdezéshez – annak másodlagos lekérdezésekhez. - @StephenHarris Right =) Ha használja next_post () az objektumon, ahelyett, hogy a_posztot használná, nem ‘ t kell lépnie a globális lekérdezésen, és nem kell ‘ használd utána a wp_reset_postdata felhasználót.
Válasz
Két különböző kontextus létezik a hurkok számára:
- main ciklus, amely az URL-kérés alapján történik, és amelyet a sablonok betöltése előtt feldolgoznak
- másodlagos
hurkok, amelyek bármilyen más módon történnek, sablonfájlokból hívják vagy más módon
Probléma a query_posts()
az, hogy a másodlagos hurok az, amely megpróbál fő lenni, és csúfosan megbukik. Így felejtsd el, hogy létezik.
A fő hurok módosításához
- ne használd a
query_posts()
- use
pre_get_posts
szűrő$query->is_main_query()
ellenőrzéssel - felváltva használhatja az
request
szűrőt ( kissé túl durva, így a fenti jobb)
Másodlagos hurok futtatásához
Használja a new WP_Query
vagy a get_posts()
, amelyek nagyjából felcserélhetők (ez utóbbi vékony burkoló az előbbihez).
Tisztításhoz
Használja a wp_reset_query()
ha közvetlenül a query_posts()
szolgáltatást használta, vagy a globális $wp_query
t elrontotta – így szinte soha nem lesz rá szüksége.
Használja a wp_reset_postdata()
ha the_post()
vagy setup_postdata()
vagy globális és vissza kell állítani a posztokkal kapcsolatos dolgok kezdeti állapotát.
Megjegyzések
- A Rarst jelentése
wp_reset_postdata()
Answe r
A query_posts($query)
használatához léteznek jogos forgatókönyvek, például:
-
Meg akarja jeleníteni a bejegyzések vagy az egyedi post típusú bejegyzések listáját egy oldalon (egy oldalsablon használatával)
-
Ezeknek a bejegyzéseknek a lapozását működőképessé szeretné tenni
Most miért szeretné megjeleníteni egy oldalon, ahelyett, hogy archív sablont használna?
-
Intuitívabb rendszergazda (az ügyfél?) – láthatják az oldalt az “Oldalak”
-
Jobb hozzáadni a menükhöz (az oldal nélkül nem az URL közvetlen hozzáadásához)
-
Ha további tartalmat (szöveget, bejegyzés indexképet vagy bármilyen egyedi metatartalmat) szeretne megjeleníteni a sablonon, akkor könnyen megszerezheti a oldal (és mindez az ügyfél számára is értelmesebb). Ellenőrizze, hogy archiválási sablont használt-e, vagy be kell kódolnia a kiegészítő tartalmat, vagy például a téma / plugin opciókat kell használnia (ami kevésbé intuitív az ügyfél számára)
Itt van egy egyszerűsített példakód (amely az oldal sablonján lenne – pl. Page-page-of-posts.php):
/** * Template Name: Page of Posts */ while(have_posts()) { // original main loop - page content the_post(); the_title(); // title of the page the_content(); // content of the page // etc... } // now we display list of our custom-post-type posts // first obtain pagination parametres $paged = 1; if(get_query_var("paged")) { $paged = get_query_var("paged"); } elseif(get_query_var("page")) { $paged = get_query_var("page"); } // query posts and replace the main query (page) with this one (so the pagination works) query_posts(array("post_type" => "my_post_type", "post_status" => "publish", "paged" => $paged)); // pagination next_posts_link(); previous_posts_link(); // loop while(have_posts()) { the_post(); the_title(); // your custom-post-type post"s title the_content(); // // your custom-post-type post"s content } wp_reset_query(); // sets the main query (global $wp_query) to the original page query (it obtains it from global $wp_the_query variable) and resets the post data // So, now we can display the page-related content again (if we wish so) while(have_posts()) { // original main loop - page content the_post(); the_title(); // title of the page the_content(); // content of the page // etc... }
Most, hogy tökéletes legyen, elkerülhetjük a query_posts()
használatát itt is, és a WP_Query
ehelyett – így:
// ... global $wp_query; $wp_query = new WP_Query(array("your query vars here")); // sets the new custom query as a main query // your custom-post-type loop here wp_reset_query(); // ...
De miért tennénk ezt, amikor ilyen szép kis funkció áll rendelkezésünkre?
Megjegyzések
- Brian, köszönöm ezt.
küzdöttem azért, hogy a pre_get_posts működjön egy oldalon, pontosan az Ön által leírt forgatókönyv szerint: az ügyfélnek egyéni mezőket / tartalmat kell hozzáadnia ahhoz, ami egyébként archív oldal lenne, tehát egy ” oldal ” létre kell hozni; az ügyfélnek látnia kell valamit, amit hozzá lehet adni a navigációs menühöz, mivel egy egyéni link hozzáadása elkerüli őket; stb. +1 tőlem!
Válasz
Módosítom a WordPress lekérdezést a functions.php fájlból:
//unfortunately, "IS_PAGE" condition doesn"t work in pre_get_posts (it"s WORDPRESS behaviour) //so you can use `add_filter("posts_where", ....);` OR modify "PAGE" query directly into template file add_action( "pre_get_posts", "myFunction" ); function myFunction($query) { if ( ! is_admin() && $query->is_main_query() ) { if ( $query->is_category ) { $query->set( "post_type", array( "post", "page", "my_postType" ) ); add_filter( "posts_where" , "MyFilterFunction_1" ) && $GLOBALS["call_ok"]=1; } } } function MyFilterFunction_1($where) { return (empty($GLOBALS["call_ok"]) || !($GLOBALS["call_ok"]=false) ? $where : $where . " AND ({$GLOBALS["wpdb"]->posts}.post_name NOT LIKE "Journal%")"; }
Megjegyzések
- érdekelné ezt a példát, de ott, ahol a záradék az egyéni metán szerepel.
Válasz
Csak azért, hogy felvázoljam az elfogadott válasz néhány fejlesztését, mivel a WordPress az idő előrehaladtával fejlődött, és néhány dolog más (most öt évvel később) :
pre_get_posts
egy szűrő bármely lekérdezés módosítására. Leggyakrabban csak a “fő lekérdezés” megváltoztatására használják:
Valójában egy cselekvési kampó. Nem szűrő, és ez hatással lesz minden lekérdezésre.
A fő lekérdezés a sablonokban a következőképpen jelenik meg:
if( have_posts() ): while( have_posts() ): the_post(); //The loop endwhile; endif;
Valójában ez sem igaz. A have_posts
függvény megismétli a global $wp_query
objektumot, amely nem csak kapcsolódik a fő lekérdezéshez. A global $wp_query;
a másodlagos lekérdezésekkel is módosítható.
function have_posts() { global $wp_query; return $wp_query->have_posts(); }
get_posts ()
Ez lényegében egy WP_Query objektum külön példányának burkolója.
Valójában manapság a WP_Query
egy osztály, tehát van egy példányunk egy osztályra.
Befejezésül: Abban az időben, amikor @StephenHarris írta, mindez valószínűleg igaz volt, de az idő múlásával a WordPress dolgai megváltoztak.
Megjegyzések
- Technikailag ez ‘ s minden szűrő a motorháztető alatt, a műveletek csak egy egyszerű szűrő. De itt igazad van, ez ‘ olyan művelet, amely hivatkozással adja át az argumentumot, így különbözik az egyszerűbb műveletektől.
-
get_posts
egy post objektum tömböt ad vissza, nem egyWP_Query
objektumot, tehát ez még mindig helyes. és aWP_Query
mindig is osztály volt, egy class = objektum példánya. - Köszönöm, @Milo, valamilyen oknál fogva helyes, a fejemben túlságosan leegyszerűsített modell volt.