WP_query (), විමසුම්_පොස්ට් () සහ පෙර_ජෙට්_පොස්ට් භාවිතා කළ යුත්තේ කවදාද?


166

මම කියෙව්වේ ac nacin's ඔබ ඊයේ විමසුම නොදන්නා අතර එය විමසන ලද හාවා වළකින් ටිකක් පහළට යවන ලදි. ඊයේට පෙර, මම (වැරදි ලෙස) query_posts()මගේ සියලු විමසුම් අවශ්‍යතා සඳහා භාවිතා කළෙමි . දැන් මම භාවිතා කිරීම ගැන ටිකක් er ානවන්තයි WP_Query(), නමුත් තවමත් අළු පැහැති ප්‍රදේශ කිහිපයක් තිබේ.

මා සිතන දේ මම නිසැකවම දනිමි:

මම පිටුවක ඕනෑම තැනක අතිරේක ලූප සාදන්නේ නම් side පැති තීරුවේ, පාද සටහනක, ඕනෑම ආකාරයක "අදාළ පෝස්ට්" යනාදිය - මට භාවිතා කිරීමට අවශ්‍යයි WP_Query(). මට කිසිදු හානියක් නොමැතිව එක පිටුවක නැවත නැවත භාවිතා කළ හැකිය. (හරිද?).

මා නොදන්නා දේ නිසැකවම

  1. මම ac nacin's pre_get_posts vs. භාවිතා කරන්නේ කවදාද WP_Query()? මම pre_get_postsදැන් සියල්ල සඳහා භාවිතා කළ යුතුද ?
  2. මට අච්චු පිටුවක ලූපය වෙනස් කිරීමට අවශ්‍ය වූ විට - මට වර්ගීකරණ සංරක්ෂිත පිටුවක් වෙනස් කිරීමට අවශ්‍ය යැයි කියමු - මම එම if have_posts : while have_posts : the_postකොටස ඉවත් කර මගේම දෑ ලියනවාද WP_Query()? නැතහොත් pre_get_postsමගේ functions.php ගොනුවේ ප්‍රතිදානය වෙනස් කරන්නේද?

tl; dr

මම මෙයින් උකහා ගැනීමට කැමති නීති රීති:

  1. query_postsතවදුරටත් භාවිතා නොකරන්න
  2. එක් පිටුවක බහු විමසුම් ධාවනය කරන විට, භාවිතා කරන්න WP_Query()
  3. ලූපයක් වෙනස් කිරීමේදී, මෙය __________________ කරන්න.

ඕනෑම ප්‍ර .ාවකට ස්තූතියි

ටෙරී

ps: මම දැක ඇති සහ කියවා ඇත්තෙමි: ඔබ WP_Query එදිරිව විමසුම්_පොස්ට් () එදිරිව get_posts () භාවිතා කළ යුත්තේ කවදාද? එය තවත් මානයක් එක් කරයි - get_posts. නමුත් කිසිසේත් ගනුදෙනු කරන්නේ නැත pre_get_posts.



@saltcod, දැන් වෙනස්, වර්ඩ්ප්රෙස් පරිණාමය උනා, මම පිළිගත් පිළිතුර සාපේක්ෂව කිහිපයක් අදහස් එකතු වේ මෙතන .
prosti

Answers:


153

ඔබ පැවසීම හරි ය:

query_postsතවදුරටත් භාවිතා නොකරන්න

pre_get_posts

pre_get_postsඕනෑම විමසුමක් වෙනස් කිරීම සඳහා පෙරණයකි . එය බොහෝ විට භාවිතා කරනුයේ 'ප්‍රධාන විමසුම' පමණක් වෙනස් කිරීමට ය:

add_action('pre_get_posts','wpse50761_alter_query');
function wpse50761_alter_query($query){

      if( $query->is_main_query() ){
        //Do something to main query
      }
}

( මෙය අතිරික්තයක් වුවද, අසත්‍යis_admin() ප්‍රතිලාභ ලැබෙනු ඇත්දැයි මම පරීක්ෂා කරමි .). ප්‍රධාන විමසුම ඔබගේ සැකිලි වල මෙසේ පෙනේ:

if( have_posts() ):
    while( have_posts() ): the_post();
       //The loop
    endwhile;
endif;

මෙම ලූපය සංස්කරණය කිරීමේ අවශ්‍යතාවය ඔබට කවදා හෝ දැනේ නම් - භාවිතා කරන්න pre_get_posts. එනම් ඔබ භාවිතා කිරීමට පෙළඹෙන්නේ නම් query_posts()- pre_get_postsඒ වෙනුවට භාවිතා කරන්න.

WP_Query

ප්‍රධාන විමසුම a හි වැදගත් අවස්ථාවකි WP_Query object. වර්ඩ්ප්‍රෙස් එය භාවිතා කරන්නේ කුමන අච්චුව භාවිතා කළ යුතුද යන්න තීරණය කිරීමට ය. නිදසුනක් ලෙස, යූආර්එල් (උදා WP_Query.

ද්විතියික ලූප සඳහා (උදා: පැති තීරුවල, හෝ 'අදාළ පෝස්ට්' ලැයිස්තු) ඔබට ඔබේම වෙනම අවස්ථාවක් නිර්මාණය කිරීමට අවශ්‍ය වනු ඇත WP_Query. උදා

$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();

සටහන wp_reset_postdata();- මෙයට හේතුව ද්විතීයික ලූපය $post'වත්මන් තනතුර' හඳුනා ගන්නා ගෝලීය විචල්‍යය අභිබවා යන බැවිනි. මෙය අත්‍යවශ්‍යයෙන්ම $postඅප සිටින තත්වයට යලි සකසයි .

get_posts ()

මෙය අත්‍යවශ්‍යයෙන්ම WP_Queryවස්තුවක වෙනම අවස්ථාවක් සඳහා එතීමකි. මෙය පශ්චාත් වස්තු සමූහයක් ලබා දෙයි. ඉහත පුඩුවේ භාවිතා කරන ක්‍රම තවදුරටත් ඔබට ලබාගත නොහැක. මෙය 'ලූප්' නොවේ, හුදෙක් පශ්චාත් වස්තුවකි.

<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>

ඔබේ ප්‍රශ්න වලට පිළිතුරු වශයෙන්

  1. pre_get_postsඔබගේ ප්‍රධාන විමසුම වෙනස් කිරීමට භාවිතා කරන්න . WP_Queryඅච්චු පිටුවල ද්විතියික ලූප සඳහා වෙනම වස්තුවක් (ක්‍රමය 2) භාවිතා කරන්න .
  2. ප්‍රධාන ලූපයේ විමසුම වෙනස් කිරීමට ඔබට අවශ්‍ය නම් භාවිතා කරන්න pre_get_posts.

WP_Query වලට වඩා යමෙකු කෙලින්ම get_posts () වෙත යන අවස්ථාවක් තිබේද?
urok93

rdrtanz - ඔව්. නිදසුනක් ලෙස ඔබට පේජින් කිරීම හෝ ඉහළින් ඇලෙන සුළු පෝස්ට් අවශ්‍ය නොවන බව පවසන්න - මෙම අවස්ථා වලදී get_posts()වඩාත් කාර්යක්ෂම වේ.
ස්ටීවන් හැරිස්

නමුත් ප්‍රධාන විමසුම වෙනස් කිරීම සඳහා අපට pre_get_posts වෙනස් කළ හැකි අතිරේක විමසුමක් එකතු නොකරන්නේද?
urok93

rdrtanz - ඔබ get_posts()ප්‍රධාන විමසුම සඳහා භාවිතා නොකරනු ඇත - එය ද්විතීයික විමසුම් සඳහා.
ස්ටීවන් හැරිස්

1
Te ස්ටෙෆෙන්හාරිස් දකුණ =) ඔබ_පෝස්ට් භාවිතා කරනවා වෙනුවට වස්තුව මත ඊලඟ_පොස්ට් () භාවිතා කරන්නේ නම්, ඔබ ගෝලීය විමසුමට පිවිසෙන්නේ නැති අතර පසුව wp_reset_postdata භාවිතා කිරීමට මතක තබා ගත යුතු නැත.
පුද්ගලික

59

ලූප සඳහා වෙනස් සන්දර්භ දෙකක් තිබේ:

  • ප්‍රධාන ඉල්ලීම URL ඉල්ලීම මත පදනම් වන අතර සැකිලි පූරණය වීමට පෙර සකසනු ලැබේ
  • අච්චු ලිපිගොනු වලින් හෝ වෙනත් ආකාරයකින් කැඳවන ද්විතියික ලූප

ගැටළුව query_posts()වන්නේ එය ද්විතීයික පුඩුවක් වන අතර එය ප්‍රධාන එකක් වීමට උත්සාහ කරන අතර අවාසනාවන්ත ලෙස අසමත් වේ. මේ අනුව එය පවතින බව අමතක කරන්න.

ප්‍රධාන ලූප වෙනස් කිරීමට

  • භාවිතා නොකරන්න query_posts()
  • චෙක්පත් pre_get_postsසමඟ පෙරණය භාවිතා $query->is_main_query()කරන්න
  • විකල්පයක් ලෙස requestපෙරණය භාවිතා කරන්න (ටිකක් රළු බැවින් ඉහත වඩා හොඳය)

ද්විතියික පුඩුවක් ධාවනය කිරීමට

භාවිතා කිරීම new WP_Queryහෝ get_posts()එකිනෙකට හුවමාරු කළ හැකි ඒවාය (දෙවැන්න කලින් තිබුනේ තුනී එතීමකි).

පිරිසිදු කිරීමට

wp_reset_query()ඔබ කෙලින්ම query_posts()ගෝලීයව භාවිතා කර හෝ අවුල් කර ඇත්නම් භාවිතා කරන්න $wp_query- එබැවින් ඔබට කිසි විටෙකත් අවශ්‍ය නොවනු ඇත.

wp_reset_postdata()ඔබ ගෝලීයව භාවිතා කර the_post()හෝ setup_postdata()අවුල් කර ඇත්නම් $postසහ පශ්චාත් ආශ්‍රිත දේවල ආරම්භක තත්වය යථා තත්වයට පත් කිරීමට අවශ්‍ය නම් භාවිතා කරන්න .


3
Rarst අදහස් කළේwp_reset_postdata()
ග්‍රෙගරි

24

භාවිතා කිරීම සඳහා නීත්‍යානුකූල අවස්ථා තිබේ query_posts($query), උදාහරණයක් ලෙස:

  1. පිටුවක පෝස්ට් ලැයිස්තුවක් හෝ අභිරුචි-පෝස්ට් වර්ගයේ පෝස්ට් එකක් පෙන්වීමට ඔබට අවශ්‍යය (පිටු අච්චුවක් භාවිතා කරමින්)

  2. ඔබට එම තනතුරු වල පේජින් කිරීම සාර්ථක කිරීමට අවශ්‍යය

දැන් ඔබට සංරක්ෂිත අච්චුවක් භාවිතා කිරීම වෙනුවට පිටුවක ප්‍රදර්ශනය කිරීමට අවශ්‍ය ඇයි?

  1. පරිපාලකයෙකුට (ඔබේ ගනුදෙනුකරුට?) එය වඩාත් බුද්ධිමත් ය - ඔවුන්ට 'පිටු' හි පිටුව දැකිය හැකිය

  2. එය මෙනු වලට එකතු කිරීම වඩා හොඳය (පිටුවකින් තොරව, ඔවුන් කෙලින්ම url එක එකතු කළ යුතුය)

  3. ඔබට අච්චුවේ අතිරේක අන්තර්ගතයන් (පෙළ, පශ්චාත් සිඟිති-රූපය හෝ ඕනෑම අභිරුචි මෙටා අන්තර්ගතයක්) ප්‍රදර්ශනය කිරීමට අවශ්‍ය නම්, ඔබට එය පහසුවෙන් පිටුවෙන් ලබා ගත හැකිය (ඒ සියල්ල පාරිභෝගිකයාටද වඩා අර්ථවත් කරයි). ඔබ සංරක්ෂිත අච්චුවක් භාවිතා කර ඇත්දැයි බලන්න, ඔබට අතිරේක අන්තර්ගතයන් දෘ c කේත කිරීමට හෝ උදාහරණයක් ලෙස තේමාව / ප්ලගීන විකල්ප සඳහා භාවිතා කිරීමට අවශ්‍ය වනු ඇත (එමඟින් පාරිභෝගිකයාට එය අඩු අවබෝධයක් ලබා දෙයි)

මෙන්න සරල කළ උදාහරණ කේතයක් (එය ඔබගේ පිටු අච්චුවේ ඇත - උදා: පිටු-පිටුව-පෝස්ට්-පීපී):

/**
 * 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...
}

දැන්, පැහැදිලිව කිවහොත් , අපට query_posts()මෙහි භාවිතා කිරීමෙන් වැළකී WP_Queryඒ වෙනුවට භාවිතා කළ හැකිය - එසේ:

// ...

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();

// ...

එහෙත්, අපට එතරම් හොඳ කුඩා කාර්යයක් ඇති විට අප එසේ කරන්නේ ඇයි?


1
බ්‍රයන්, ඒකට ස්තූතියි. ඔබ විස්තර කරන සිද්ධියේ හරියටම පිටුවක වැඩ කිරීමට pre_get_posts ලබා ගැනීමට මම වෙහෙස වී සිටිමි: සේවාදායකයාට අභිරුචි ක්ෂේත්‍ර / අන්තර්ගතයන් සංරක්ෂිත පිටුවක් වනු ඇති දේට එකතු කළ යුතුය, එබැවින් "පිටුවක්" සෑදිය යුතුය; අභිරුචි සබැඳියක් එක් කිරීමෙන් ඒවායින් ගැලවී යන බැවින් සේවාදායකයාට nav මෙනුවට එකතු කිරීමට යමක් දැකීමට අවශ්‍ය වේ; ආදිය +1 මගෙන්!
විල් ලැනී

2
එය "pre_get_posts" භාවිතයෙන්ද කළ හැකිය. මගේ අභිරුචි පෝස්ට් වර්ග අභිරුචි අනුපිළිවෙලකට සහ අභිරුචි පෙරණයක් සමඟ ලැයිස්තුගත කිරීමට "ස්ථිතික මුල් පිටුවක්" තිබීම සඳහා මම එය කළෙමි. මෙම පිටුව ද පේජින් කර ඇත. එය ක්‍රියාත්මක වන්නේ කෙසේදැයි බැලීමට මෙම ප්‍රශ්නය පරීක්ෂා කරන්න: wordpress.stackexchange.com/questions/30851/… එබැවින් කෙටියෙන් කිවහොත්, විමසුම්_ පෝස්ට් භාවිතා කිරීම සඳහා තවත් නීත්‍යානුකූල අවස්ථාවක් නොමැත;)
2ndkauboy

1
මක්නිසාද යත් "පිටුවක ප්‍රධාන විමසුම ප්‍රතිස්ථාපනය කිරීම සඳහා මෙය භාවිතා කිරීමෙන් පිටු පැටවීමේ වේලාව වැඩි කළ හැකි බව සැලකිල්ලට ගත යුතුය. නරකම අවස්ථාවන්හිදී අවශ්‍ය ප්‍රමාණය හෝ ඊට වැඩි ප්‍රමාණයක් දෙගුණ කිරීමට වඩා වැඩි ය. භාවිතයට පහසු වුවත්, ශ්‍රිතය ව්‍යාකූලත්වයට ද ගොදුරු වේ. පසුව ගැටළු. මුලාශ්‍රය codex.wordpress.org/Function_Reference/query_posts
Claudiu Creanga

මෙම පිළිතුර සියලු ආකාරයේ වැරදි ය. අභිරුචි පෝස්ට් වර්ගයට සමාන URL සමඟ ඔබට WP හි "පිටුවක්" සෑදිය හැකිය. EG ඔබේ CPT කෙසෙල් නම්, ඔබට එකම URL සමඟ කෙසෙල් නම් පිටුවක් ලබා ගත හැකිය. එවිට ඔබ siteurl.com/bananas සමඟ අවසන් වනු ඇත. ඔබගේ තේමා ෆෝල්ඩරයේ ලේඛනාගාරය- bananas.php ඇති තාක් කල්, එය අච්චුව භාවිතා කර ඒ වෙනුවට එම පිටුව “අභිබවා යයි”. අනෙක් අදහස් වලින් එකක සඳහන් කර ඇති පරිදි, මෙම "ක්‍රමය" භාවිතා කිරීමෙන් WP සඳහා වැඩ බර මෙන් දෙගුණයක් නිර්මාණය වේ, එබැවින් කිසි විටෙකත් භාවිතා නොකළ යුතුය.
දෙමුහුන් වෙබ් දේව්

9

මම වර්ඩ්ප්‍රෙස් විමසුම functions.php වෙතින් වෙනස් කරමි:

//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%')"; 
}

මෙම උදාහරණය බැලීමට උනන්දුවක් දක්වන නමුත් අභිරුචි මෙටා හි වගන්තිය ඇති තැන.
වෙල්ච්

7

වර්ඩ්ප්‍රෙස් කාලයාගේ ඇවෑමෙන් පරිණාමය වී ඇති අතර පිළිගත් පිළිතුරෙහි යම් යම් වැඩිදියුණු කිරීම් ගෙනහැර දැක්වීමට සහ සමහර දේවල් දැන් වෙනස් වී ඇත (අවුරුදු පහකට පසුව):

pre_get_postsඕනෑම විමසුමක් වෙනස් කිරීම සඳහා පෙරණයකි. එය බොහෝ විට භාවිතා කරනුයේ 'ප්‍රධාන විමසුම' පමණක් වෙනස් කිරීමට ය:

ඇත්තෙන්ම ක්‍රියාකාරී කොක්කකි. පෙරනයක් නොවේ, එය ඕනෑම විමසුමකට බලපායි.

ප්‍රධාන විමසුම ඔබගේ සැකිලි වල මෙසේ පෙනේ:

if( have_posts() ):
    while( have_posts() ): the_post();
       //The loop
    endwhile;
endif;

ඇත්ත වශයෙන්ම මෙය ද සත්‍ය නොවේ. එම උත්සවයට have_postsඑම දයානන්ද් global $wp_queryසම්බන්ධ නැති බව වස්තුවක් පමණක් ප්රධාන ප්රශ්නයකට. global $wp_query;ද්විතීයික විමසුම් සමඟ ද වෙනස් කළ හැකිය.

function have_posts() {
    global $wp_query;
    return $wp_query->have_posts();
}

get_posts ()

මෙය අත්‍යවශ්‍යයෙන්ම WP_Query වස්තුවක වෙනම අවස්ථාවක් සඳහා එතීමකි.

ඇත්ත වශයෙන්ම, වර්තමානයේ WP_Queryපන්තියක් බැවින් අපට පන්තියක උදාහරණයක් තිබේ.


නිගමනය කිරීම සඳහා: ස්ටෙෆන් හැරිස් ලියන විට බොහෝ දුරට මේ සියල්ල සත්‍ය විය හැකි නමුත් කාලයත් සමඟ වර්ඩ්ප්‍රෙස් හි දේවල් වෙනස් වී ඇත.


තාක්ෂණික වශයෙන්, එය සියල්ලම හුඩ් යට පෙරහන්, ක්‍රියාවන් සරල පෙරණයක් පමණි. නමුත් ඔබ මෙහි නිවැරදි ය, එය තර්කයක් යොමු කිරීමකින් සම්මත කරන ක්‍රියාවකි, එය වඩාත් සරල ක්‍රියාවන්ට වඩා වෙනස් වන්නේ එලෙස ය.
මයිලෝ

get_postsපශ්චාත් වස්තු සමූහයක් නැවත ලබා දෙයි, WP_Queryවස්තුවක් නොවේ , එබැවින් එය තවමත් නිවැරදි ය. සහ WP_Queryසෑම විටම පන්තියක් වී ඇත, උදාහරණයක් ලෙස පන්තියේ = වස්තුවක.
මයිලෝ

ස්තූතියි, ilo මයිලෝ, කිසියම් හේතුවක් නිසා මගේ හිසෙහි ආකෘතිය සරල කර ඇත.
prosti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.