结合 WP_Query 与主查询(the Main Query)

无论你活成什么样貌,背地里都会有人对你说三道四。不申辩不计较一笑了之,其实就是最好的蔑视。
本文是《掌握 WP_Query》专题的第 14 篇,共 19 篇:
  • WP_Query 参数:自定义字段(Custom Fields)
  • WP_Query 参数:分类法(Taxonomies)
  • 掌握 WP_Query : 入门介绍
  • 掌握 WP_Query:教你使用Loop循环
  • 掌握 WP_Query:相关的函数
  • 掌握 WP_Query:行动器和过滤器
  • 掌握 WP_Query:WP_Query类的属性和方法
  • WP_Query 参数:文章、页面和文章类型
  • WP_Query 参数:分类和标签
  • WP_Query 参数:日期
  • WP_Query 参数:状态、排序和分页
  • WP_Query 参数:作者、搜索、密码、权限、缓存和返回字段
  • 掌握 WP_Query:10个有用的例子
  • 结合 WP_Query 与主查询(the Main Query)
  • 掌握 WP_User_Query
  • 掌握 WP_Comment_Query
  • 掌握 WP_Meta_Query 和 WP_Date_Query
  • WordPress 4.1的查询改进
  • 掌握 WP_Query:结尾

到目前为止,在这个系列中,你已经学习了如何在你的主题或插件中使用 WP_Query 创建自定义查询。在大多数情况下,你将使用 WP_Query 设置独立于主查询(the Main Query)的参数来查询,但如果你希望包含主查询的参数在你的参数中,你该怎么做?

注:由于时间精力有限,本好代码教程没办法翻译分享,希望朋友们可以加入我们,帮助我们进行翻译,有小酬谢,有意者请联系倡萌QQ 745722006(注明:好代码教程翻译)。

以下为原文:http://code.tutsplus.com/tutorials/combining-wp_query-with-the-main-query--cms-23209

So far in this series you've learned how to use WP_Query to create custom queries for use in your theme or plugins.

In most cases, you'll use WP_Query with a completely new set of arguments which are separate from that in the main query, but what if you want to include the main query in your arguments?

Examples of when you might want to do this include:

  • on a category or taxonomy page, displaying only posts of one post type
  • on a category page, displaying posts with the current category and another category or a tag or taxonomy term
  • on a page for a post type, just displaying posts with certain metadata

I could go on—there are plenty of opportunities for combining the main query with your own custom query.

I'm going to demonstrate this with three examples: the first one will be a simple example with one loop; the second will use foreach to output multiple loops, one for each post type; and the third will output two post types on a category archive by using two separate queries.

Defining a Variable Based on the Main Query

However you're going to combine your main query with WP_Query, you need to store the current query object in a way that makes it easy to use in your WP_Query arguments. The easiest way to do this is by assigning it to a variable.

You do this before defining your WP_Query arguments, like so:

1
$mainquery = get_queried_object();

$mainquery = get_queried_object();

The get_queried_object() function returns the currently queried object, whatever that may be. On a single post, it will just return the post object, while on an archive it will return the category, tag, term object or whatever object relates to the archive. It returns the ID of the queried object.

You can then use this $mainquery variable in your WP_Query arguments. Now let's take a look at some examples.

Example 1: Displaying Only Posts of One Post Type on a Category Page

Let's say your site has a custom post type added to it and you've enabled categories for that custom post type. On the category archive for each category, you don't want to display posts: instead you want to display posts of your new post type—let's call it product.

Your query might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

$mainquery = get_queried_object();

$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'product'
);

// Custom query.
$query = new WP_Query( $args );

// Check that we have query results.
if ( $query->have_posts() ) {

    // Start looping over the query results.
    while ( $query->have_posts() ) {

        $query->the_post();

        // Contents of the queried post results go here.

    }

}

// Restore original post data.
wp_reset_postdata();

?>

<?php $mainquery = get_queried_object(); $args = array ( 'category_name' => $mainquery->slug, 'post_type' => 'product' ); // Custom query. $query = new WP_Query( $args ); // Check that we have query results. if ( $query->have_posts() ) { // Start looping over the query results. while ( $query->have_posts() ) { $query->the_post(); // Contents of the queried post results go here. } } // Restore original post data. wp_reset_postdata(); ?>

Because the category_name parameter I've used above takes the category slug as its argument, you need to add ->slug after the variable to output the category slug.

This gives you a query which fetches posts of the product post type from the database with the currently queried category. You'd use it on the category.php page template.

Note: You could also achieve this result using the pre_get_posts hook to amend the main query, combined with a conditional function to check for category archives.

Example 2: Combining the Main Query With WP_Query and foreach to Output Multiple Loops

The next example will output all of the posts for the current category page, but instead of showing them all in one block it will separate them by post type.

This means you can sort your post types into blocks or columns on your page using CSS, or just separate them out into different lists.

To do this, you'd use the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php

$mainquery = get_queried_object();

$post_types = get_post_types();

foreach ( $post_types as $post_type ) {

    $args = array(
        'category_name' => $mainquery->slug,
        'post_type' => $post_type
    );

    // Custom query.
    $query = new WP_Query( $args );

    // Check that we have query results.
    if ( $query->have_posts() ) {

        // Start looping over the query results.
        while ( $query->have_posts() ) {

            $query->the_post();

            // Contents of the queried post results go here.

        }

    }

    // Restore original post data.
    wp_reset_postdata();

}

?>

<?php $mainquery = get_queried_object(); $post_types = get_post_types(); foreach ( $post_types as $post_type ) { $args = array( 'category_name' => $mainquery->slug, 'post_type' => $post_type ); // Custom query. $query = new WP_Query( $args ); // Check that we have query results. if ( $query->have_posts() ) { // Start looping over the query results. while ( $query->have_posts() ) { $query->the_post(); // Contents of the queried post results go here. } } // Restore original post data. wp_reset_postdata(); } ?>

This uses the $mainquery variable we used before, but it also adds a $post_types variable to store all of the post types registered on the site, and a $post_type variable to store each individual post type in turn.

Example 3: Two Separate Queries for Two Post Types

The final example is similar to the second one, but separates out the post types into two separate queries, each with its own distinct loop. This gives you more control over what's displayed for each, so you could display posts differently from products, maybe including a featured image for products or giving them a different layout.

Let's say your site has the product post type registered, with categories enabled for it, and you're also writing blog posts with the same categories. On each category archive page you want to display the most recent ten posts, and then you want to display a list of all products in the same category.

To do this, you'd use something like this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php

$mainquery = get_queried_object();

// First query arguments for posts.
$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'post',
    'posts_per_page' => '10'
);

// Custom query.
$query = new WP_Query( $args );

// Check that we have query results.
if ( $query->have_posts() ) {

    // Start looping over the query results.
    while ( $query->have_posts() ) {

        $query->the_post();

        // Contents of the queried post results go here.

    }

}

// Restore original post data.
wp_reset_postdata();

// Second query arguments for products.
$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'product',
    'posts_per_page' => '-1'
);

// Custom query.
$query = new WP_Query( $args );

// Check that we have query results.
if ( $query->have_posts() ) {

    // Start looping over the query results.
    while ( $query->have_posts() ) {

        $query->the_post();

        // Contents of the queried post results go here.

    }

}

// Restore original post data.
wp_reset_postdata();

?>

<?php $mainquery = get_queried_object(); // First query arguments for posts. $args = array ( 'category_name' => $mainquery->slug, 'post_type' => 'post', 'posts_per_page' => '10' ); // Custom query. $query = new WP_Query( $args ); // Check that we have query results. if ( $query->have_posts() ) { // Start looping over the query results. while ( $query->have_posts() ) { $query->the_post(); // Contents of the queried post results go here. } } // Restore original post data. wp_reset_postdata(); // Second query arguments for products. $args = array ( 'category_name' => $mainquery->slug, 'post_type' => 'product', 'posts_per_page' => '-1' ); // Custom query. $query = new WP_Query( $args ); // Check that we have query results. if ( $query->have_posts() ) { // Start looping over the query results. while ( $query->have_posts() ) { $query->the_post(); // Contents of the queried post results go here. } } // Restore original post data. wp_reset_postdata(); ?>

You'd then write each loop differently to output different data for each post type.

Summary

As you can see from the examples above, it's possible to use WP_Query not only to create completely custom queries separate from the main query, but also to incorporate the currently queried object and create more powerful queries on archive pages.

The examples above can also be done with other archive types: for taxonomies, authors, dates and more. See if you can come up with more possibilities!

以上就是结合 WP_Query 与主查询(the Main Query)。如果当初我们能坚持的走下去,今天的结局就不会这么匆匆收场。更多关于结合 WP_Query 与主查询(the Main Query)请关注haodaima.com其它相关文章!

标签: WP_Query Main