একটি একক জিজ্ঞাসা
এই সম্পর্কে আরও কিছুটা ভেবেছিলেন এবং এমন একটি সুযোগ রয়েছে যে আপনি একটি একক / মূল প্রশ্নের সাথে যেতে পারেন। বা অন্য কথায়: আপনি যখন ডিফল্টটির সাথে কাজ করতে পারেন তখন দুটি অতিরিক্ত প্রশ্নের প্রয়োজন নেই। এবং যদি আপনি কোনও ডিফল্ট সাথে কাজ করতে না পারেন তবে আপনি কোয়েরিটি কতগুলি লুপটি বিভক্ত করতে চান তা বিবেচনা করেই আপনার একক কোয়েরির চেয়ে বেশি প্রয়োজন হবে না।
পূর্বশর্ত
প্রথমে আপনাকে pre_get_posts
ফিল্টারটির মধ্যে প্রয়োজনীয় মানগুলি সেট করতে হবে (আমার অন্যান্য উত্তরে দেখানো হয়েছে) । সেখানে আপনি সম্ভবত সেট posts_per_page
এবং cat
। pre_get_posts
ফিল্টার ছাড়াই উদাহরণ :
$catID = 1;
$catQuery = new WP_Query( array(
'posts_per_page' => -1,
'cat' => $catID,
) );
// Add a headline:
printf( '<h1>%s</h1>', number_format_i18n( $catQuery->found_posts )
.__( " Posts filed under ", 'YourTextdomain' )
.get_cat_name( $catID ) );
একটি বেস নির্মাণ
আমাদের পরবর্তী জিনিসটি হ'ল একটি ছোট্ট কাস্টম প্লাগইন (বা functions.php
আপডেট বা থিম পরিবর্তনের সময় আপনি যদি এটিকে ঘুরিয়ে নিতে কিছু মনে করেন না তবে এটি কেবল আপনার ফাইলে রাখুন):
<?php
/**
* Plugin Name: (#130009) Merge Two Queries
* Description: "Merges" two queries by using a <code>RecursiveFilterIterator</code> to divide one main query into two queries
* Plugin URl: http://wordpress.stackexchange.com/questions/130009/how-to-merge-two-queries-together
*/
class ThumbnailFilter extends FilterIterator implements Countable
{
private $wp_query;
private $allowed;
private $counter = 0;
public function __construct( Iterator $iterator, WP_Query $wp_query )
{
NULL === $this->wp_query AND $this->wp_query = $wp_query;
// Save some processing time by saving it once
NULL === $this->allowed
AND $this->allowed = $this->wp_query->have_posts();
parent::__construct( $iterator );
}
public function accept()
{
if (
! $this->allowed
OR ! $this->current() instanceof WP_Post
)
return FALSE;
// Switch index, Setup post data, etc.
$this->wp_query->the_post();
// Last WP_Post reached: Setup WP_Query for next loop
$this->wp_query->current_post === $this->wp_query->query_vars['posts_per_page'] -1
AND $this->wp_query->rewind_posts();
// Doesn't meet criteria? Abort.
if ( $this->deny() )
return FALSE;
$this->counter++;
return TRUE;
}
public function deny()
{
return ! has_post_thumbnail( $this->current()->ID );
}
public function count()
{
return $this->counter;
}
}
এই প্লাগইনটি একটি কাজ করে: এটি পিএইচপি এসপিএল (স্ট্যান্ডার্ড পিএইচপি গ্রন্থাগার) এবং এর ইন্টারফেস এবং আইট্রেটারগুলি ব্যবহার করে। আমরা এখন যা পেয়েছি তা হ'ল FilterIterator
আমাদের লুপ থেকে আইটেমগুলি সুবিধামত সরানোর অনুমতি দেয়। এটি পিএইচপি এসপিএল ফিল্টার আইট্রেটারকে প্রসারিত করে যাতে আমাদের সবকিছু সেট করার দরকার নেই। কোডটি ভালভাবে মন্তব্য করা হয়েছে তবে এখানে কয়েকটি নোট রয়েছে:
accept()
বা না - পদ্ধতি মানদণ্ড ঐ আইটেমটির লুপিং অনুমতি নির্ধারণ করতে দেয়।
- সেই পদ্ধতির অভ্যন্তরে আমরা ব্যবহার করি
WP_Query::the_post()
, যাতে আপনি কেবল আপনার টেম্পলেট ফাইল লুপে প্রতিটি টেম্পলেট ট্যাগ ব্যবহার করতে পারেন।
- এবং পাশাপাশি আমরা শেষ আইটেমে পৌঁছানোর পরে লুপটি পর্যবেক্ষণ করছি এবং পোস্টগুলিকে রিওয়াইন্ড করছি। এটি আমাদের ক্যোয়ারীটি পুনরায় সেট না করে লুপ ট্রাফকে অসীম পরিমাণে লুপের অনুমতি দেয়।
- সেখানে যে অংশ নয় একটি কাস্টম পদ্ধতি
FilterIterator
চশমা: deny()
। এই পদ্ধতিটি বিশেষত সুবিধাজনক কারণ এটিতে কেবল আমাদের "প্রক্রিয়া বা না" স্টেস্টমেন্ট রয়েছে এবং আমরা ওয়ার্ডপ্রেস টেম্পলেট ট্যাগগুলি বাদে কোনও কিছু না জানার পরে পরবর্তী ক্লাসে সহজেই এটিকে ওভাররাইট করতে পারি।
কীভাবে লুপ করবেন?
এই নতুন ইটারেটর সঙ্গে, আমরা প্রয়োজন হবে না if ( $customQuery->have_posts() )
এবং while ( $customQuery->have_posts() )
আর। foreach
সমস্ত প্রয়োজনীয় চেকগুলি ইতিমধ্যে আমাদের জন্য সম্পন্ন হওয়ায় আমরা একটি সহজ বিবৃতি দিয়ে যেতে পারি। উদাহরণ:
global $wp_query;
// First we need an ArrayObject made out of the actual posts
$arrayObj = new ArrayObject( $wp_query->get_posts() );
// Then we need to throw it into our new custom Filter Iterator
// We pass the $wp_query object in as second argument to keep track with it
$primaryQuery = new ThumbnailFilter( $arrayObj->getIterator(), $wp_query );
অবশেষে আমাদের একটি ডিফল্ট foreach
লুপ ছাড়া আর কিছুই লাগবে না । আমরা এমনকি the_post()
সমস্ত টেম্পলেট ট্যাগগুলি ড্রপ করতে এবং ব্যবহার করতে পারি । গ্লোবাল $post
অবজেক্ট সর্বদা সিঙ্কে থাকবে।
foreach ( $primaryQuery as $post )
{
var_dump( get_the_ID() );
}
সহায়ক লুপগুলি
এখন খুব সুন্দর বিষয় হ'ল প্রতিটি পরবর্তী ক্যোয়ারী ফিল্টার হ্যান্ডেল করা বেশ সহজ: deny()
পদ্ধতিটি সহজভাবে সংজ্ঞায়িত করুন এবং আপনি আপনার পরবর্তী লুপের জন্য প্রস্তুত। $this->current()
সর্বদা আমাদের বর্তমানে লুপ করা পোস্টে নির্দেশ করবে।
class NoThumbnailFilter extends ThumbnailFilter
{
public function deny()
{
return has_post_thumbnail( $this->current()->ID );
}
}
আমরা যেমন সংজ্ঞায়িত করেছি যে আমরা এখন deny()
থাম্বনেইলযুক্ত প্রতিটি পোস্ট লুপ করছি, তারপরে আমরা তাত্ক্ষণিকভাবে থাম্বনেল ছাড়াই সমস্ত পোস্ট লুপ করতে পারি:
foreach ( $secondaryQuery as $post )
{
var_dump( get_the_title( get_the_ID() ) );
}
এটা পরীক্ষা করো.
নিম্নলিখিত পরীক্ষার প্লাগইনটি গিস্টহাবের উপর গিস্ট হিসাবে উপলব্ধ। কেবল এটি আপলোড এবং সক্রিয় করুন। এটি loop_start
কর্মের কলব্যাক হিসাবে প্রতিটি লুপযুক্ত পোস্টের আইডি আউটপুট / ডাম্প করে । এর অর্থ এটি আপনার সেটআপ, পোস্টের সংখ্যা এবং কনফিগারেশনের উপর নির্ভর করে বেশ খানিকটা আউটপুট পেতে পারে। দয়া করে কিছু গর্ভপাত বিবৃতি যুক্ত করুন এবং var_dump()
আপনি কী দেখতে চান এবং কোথায় আপনি এটি দেখতে চান তার শেষে পরিবর্তিত করুন । এটি ধারণার একটি প্রমাণ মাত্র।