Wordpress - multiple WP Query objects into one?

2019-02-18 22:33发布

问题:

In Wordpress it's possible to create own WP Querys for the loop. An example is this:

$my_query = new WP_Query(array('post_parent' => 3, 'post_type' => 'page'));

Another example is this:

$my_query = new WP_Query(array('cat' => 1, 'post_type' => 'post'));

I want a loop that presents pages AND posts from the same loop.

Now to my question. Is it possible to combine these two objects into one? If it is, how? I'm NOT interested in creating two different loops.

回答1:

what you want would translate to a WHERE ... OR ... condition or a UNION in SQL, eg.

SELECT * FROM posts WHERE (post_parent = 3 AND post_type = 'page') 
  OR (cat = 1 AND post_type = 'post')

or

SELECT * FROM posts WHERE post_parent = 3 AND post_type = 'page'
  UNION
SELECT * FROM posts WHERE cat = 1 AND post_type = 'post'

from looking at the source and the way WP constructs SQL from WP_Query(), i don't think this is possible: there is no OR'ing nor UNION of query vars.

the only thing that comes to my mind is writing a plugin that implements the posts_where filter (applied to the WHERE clause of the query that returns the post array). you could call this plugin with your different WP Querys, and the plugin would get their WHERE parts and could OR them together.

see also http://codex.wordpress.org/Custom_Queries



回答2:

I found the solution myself. I use setup_postdata to parse an SQL Query.

The solution



回答3:

In case you don't want to do it with SQL, this is how I did my search page.

Basic problem: When doing a meta_query, wordpress thinks I want the condition to be joined with "AND" instead of "OR".

So Wordpress looks for a page with title/content = "myContent" AND the aioseop_keyword "myContent". This (in my case) lead to zero results, despite there was a page with matching SEO keyword.

To get around this, I make two queries. Sounds simple, BUT: the Loop didn't want to recognize the posts, despite there are posts in the $post object. I found this solution after taking a look on the have_posts() function : it refers to other variables than just the $post object.

$term = get_search_query(); // same as $_GET['s']

# the normal search:
$wordpress_keyword_search =& new WP_Query(array(
  's'         => $term,
  'showposts' => -1
));

# now push already found post IDs to an array, so we can exclude them from the meta search.
foreach ($wordpress_keyword_search->posts as $post_)
  $exclusion[] = $post_->ID;


# now do the meta query search
$aioseop_keyword_search =& new WP_Query(array(
  'post__not_in' => $exclusion,
  'post_type' => 'any',
  'showposts' => -1,
  'meta_query' => array(            
    array(
      'key'       => '_aioseop_keywords',
      'value'     => $term,
      'compare'   => 'LIKE',
    )
  )
));

# merge the two array posts.
# post_count and found_posts must be added together also. 
# otherwise have_posts() returns false.
# see: http://core.trac.wordpress.org/browser/tags/3.6.1/wp-includes/query.php#L2886

$wordpress_keyword_search->posts       = array_merge($wordpress_keyword_search->posts, $aioseop_keyword_search->posts );
$wordpress_keyword_search->found_posts = $wordpress_keyword_search->found_posts + $aioseop_keyword_search->found_posts;
$wordpress_keyword_search->post_count  = $wordpress_keyword_search->post_count + $aioseop_keyword_search->post_count;

Then use this in a simple loop:

if ($wordpress_keyword_search->have_posts()) {
  while($wordpress_keyword_search->have_posts()) {
    $wordpress_keyword_search->the_post();
    # now you simply can:
    the_title();
    the_content();

  }
} else {
  echo '<p>Sorry, no posts found</p>';
}