WP_Query 参数:分类法(Taxonomies)

夏夜,天上缀满了闪闪发光的星星,像细碎的流沙铺成的银河斜躺在青色的天宇上。大地已经沉睡了。我任了性,纵容思念开成一片海,定格成回忆里抹不去的风景。太阳把大海映红了,好像得大海披上了一层红纱。
本文是《掌握 WP_Query》专题的第 2 篇,共 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 的各种参数。

WP_Query 有很多可用的参数,使它变得非常灵活。正如你可以使用它来查询存储在 wp_posts 表的任何内容一样,它有参数可用于不同的查询阵列获取你想要的内容。

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

以下为原文:http://code.tutsplus.com/tutorials/wp_query-arguments-taxonomies--cms-23090

So far in this series, you've learned how WP_Query is structured and what its properties and methods are. Now we're looking at the various arguments you can use with WP_Query and how you code them.

WP_Query has a large number of possible arguments, which makes it extremely flexible. As you can use it to query just about anything held in your wp_posts table, it has arguments for every permutation of query you might want to run on your content.

In this tutorial I'll look at arguments for querying taxonomy terms.

A Recap on How Arguments Work in WP_Query

Before we start, let's have a quick recap on how arguments work in WP_Query. When you code WP_Query in your themes or plugins, you need to include four main elements:

  • the arguments for the query, using parameters which will be covered in this tutorial
  • the query itself
  • the loop
  • finishing off: closing if and while tags and resetting post data

In practice this will look something like the following:

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

$args = array(
    // Arguments for your query.
);

// 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 $args = array( // Arguments for your query. ); // 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(); ?>

The arguments are what tells WordPress what data to fetch from the database and it's those that I'll cover here. So all we're focusing on here is the first part of the code:

1
2
3
$args = array(
    // Arguments for your query.
);

$args = array( // Arguments for your query. );

As you can see, the arguments are contained in an array. You'll learn how to code them as you work through this tutorial.

Coding Your Arguments

There is a specific way to code the arguments in the array, which is as follows:

1
2
3
4
5
$args = array(
    'parameter1' => 'value',
    'parameter2' => 'value',
    'parameter3' => 'value'
);

$args = array( 'parameter1' => 'value', 'parameter2' => 'value', 'parameter3' => 'value' );

You must enclose the parameters and their values in single quotation marks, use => between them, and separate them with a comma. If you get this wrong, WordPress may not add all of your arguments to the query or you may get a white screen.

The Taxonomy Parameters

Setting parameters for taxonomy terms is a little more complicated than for categories and tags since you use tax_query. Within this argument you write a nested array of arguments to specify the taxonomy and term using these parameters:

  • taxonomy (string): Taxonomy.
  • field (string): Select taxonomy term by ('term_id (default), 'name' or 'slug').
  • terms (int/string/array): Taxonomy term(s).
  • include_children (boolean): Whether or not to include children for hierarchical taxonomies. Defaults to true.
  • operator (string): Operator to test. Possible values are 'IN' (default), 'NOT IN', 'AND'.

The fact that you have the operator parameter means you don't need to choose from one of a range of available arguments to define whether you're including or excluding terms (as you do for tags and categories), but use tax_query for everything taxonomy-related instead.

If you want to query for multiple taxonomies, you can also use the relation parameter before all of your arrays (one for each taxonomy) with AND or OR to specify whether you want to find posts with all of the terms or any of them.

This is most easily explained with some examples.

Querying for One Taxonomy Term

This is the simplest scenario and involves just using one nested array:

1
2
3
4
5
6
7
8
9
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'field' => 'slug',
            'terms' => 'my-term-slug',
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'field' => 'slug', 'terms' => 'my-term-slug', ) ) );

The above queries for posts with the my-term-slug term in the my-taxonomy taxonomy. Note that you also need to use the field parameter to identify which field you're using to identify the term, unless you're using the term ID which is the default. If you wanted to use the term ID you'd use something like this:

1
2
3
4
5
6
7
8
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'terms' => '11'
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'terms' => '11' ) ) );

Using the ID makes it harder for you to identify what your query is looking for at a later date, but avoids any potential problems if you think your users might edit the term slugs.

Querying For Multiple Terms in One Taxonomy

If you want to identify posts with one or more of an array of terms in the same taxonomy, you still write one nested array, but add an array of terms.

For example, to query posts with any of a list of term IDs from your taxonomy, you use:

1
2
3
4
5
6
7
8
9
10
11
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'terms' => array(
                '11',
                '12'
            )
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'terms' => array( '11', '12' ) ) ) );

But what if you wanted to query posts with all of these terms? You'll need to use the operator parameter inside your nested array:

1
2
3
4
5
6
7
8
9
10
11
12
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'terms' => array(
                '11',
                '12'
            ),
            'operator' => 'AND'
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'terms' => array( '11', '12' ), 'operator' => 'AND' ) ) );

Note that the first example actually uses the IN operator to find posts with any of the terms, but as this is the default you don't have to specify it in your arguments.

Another scenario is if you want to query for posts which don't have any of an array of terms in one taxonomy, which you do like this:

1
2
3
4
5
6
7
8
9
10
11
12
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'terms' => array(
                '11',
                '12'
            ),
            'operator' => 'NOT IN'
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'terms' => array( '11', '12' ), 'operator' => 'NOT IN' ) ) );

Here I've replaced the AND operator with NOT IN, which means WordPress will find posts without any of the terms in the array.

Note that if you prefer to use slugs instead of term IDs, you can do so with any of these scenarios. The last example would look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'field' => 'slug',
            'terms' => array(
                'my-slug',
                'your-slug'
            ),
            'operator' => 'NOT IN'
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'field' => 'slug', 'terms' => array( 'my-slug', 'your-slug' ), 'operator' => 'NOT IN' ) ) );

Another scenario is if you want to query for posts that have one term but not another. This uses the INoperator (which you don't need to include as it's the default), with a minus sign before the ID of any terms you want to exclude:

1
2
3
4
5
6
7
8
9
10
11
$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'my-taxonomy',
            'terms' => array(
                '11',
                '-12'
            )
        )
    )
);

$args = array( 'tax_query' => array( array( 'taxonomy' => 'my-taxonomy', 'terms' => array( '11', '-12' ) ) ) );

This queries posts with term 11 but not term 12.

Querying Terms From Multiple Taxonomies

If you want to work with more than one taxonomy, you'll need to create more than one array. Let's look at the simplest example, to query posts with one term from taxonomy1 and one term from taxonomy2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$args = array(
    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( 'slug-one' )
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => array( 'slug-two' )
        )
    )
);

$args = array( 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'taxonomy1', 'field' => 'slug', 'terms' => array( 'slug-one' ) ), array( 'taxonomy' => 'taxonomy2', 'field' => 'slug', 'terms' => array( 'slug-two' ) ) ) );

Here I've written two nested arrays: one for each taxonomy, using the same arguments as I did for the examples using just one taxonomy. I've preceded these with the relation argument. You need to include the relation argument to tell WordPress whether it's looking for all or some of the posts output by each array. This works as follows:

  • If you use 'relation' => 'AND', WordPress will fetch the posts specified in the first array and the second array. So in the example above, only posts with both the slug-one slug in taxonomy1 and the slug-two slug in taxonomy2 will be queried.
  • If you use 'relation' => 'OR', WordPress will fetch posts output by the first array or the second array. So in this case you'll get posts with either the slug-one slug or the slug-two slug (or both).

This is the code you'd use if you were looking for posts with either of the two slugs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$args = array(
    'tax_query' => array(
        'relation' => 'OR',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( 'slug-one' )
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => array( 'slug-two' )
        )
    )
);

$args = array( 'tax_query' => array( 'relation' => 'OR', array( 'taxonomy' => 'taxonomy1', 'field' => 'slug', 'terms' => array( 'slug-one' ) ), array( 'taxonomy' => 'taxonomy2', 'field' => 'slug', 'terms' => array( 'slug-two' ) ) ) );

You can also look for more than one term in a given taxonomy by adding it to the array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$args = array(
    'tax_query' => array(
        'relation' => 'OR',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( 'slug-one' )
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => array(
                'slug-two',
                'slug-three'
            )
        )
    )
);

$args = array( 'tax_query' => array( 'relation' => 'OR', array( 'taxonomy' => 'taxonomy1', 'field' => 'slug', 'terms' => array( 'slug-one' ) ), array( 'taxonomy' => 'taxonomy2', 'field' => 'slug', 'terms' => array( 'slug-two', 'slug-three' ) ) ) );

By combining the relation argument with nested queries also using the operator argument, you can create quite complex queries. The arguments below would query posts with a term from one taxonomy but without a term from another taxonomy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$args = array(
    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( 'slug-one' ),
            'operator' => 'NOT IN'
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => array( 'slug-two' )
        )
    )
);

$args = array( 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'taxonomy1', 'field' => 'slug', 'terms' => array( 'slug-one' ), 'operator' => 'NOT IN' ), array( 'taxonomy' => 'taxonomy2', 'field' => 'slug', 'terms' => array( 'slug-two' ) ) ) );

Note that I've used 'relation' => 'AND' here: if I used OR, it would query posts with slug-two and posts without slug-one, rather than posts which have slug-two but not slug-one, which is what I'm looking for.

You could conceivably take this further to query your taxonomies' terms however you wanted: using theoperator argument in both nested queries or adding an additional nested query to query terms in another taxonomy.

A Note on the tax Argument

You may be wondering why I haven't included the {tax} argument, where you simply write your argument as follows:

1
2
3
$args = array(
    'taxonomy1' => 'slug-one'
);

$args = array( 'taxonomy1' => 'slug-one' );

You may be familiar with this way of querying taxonomies if you've done it in the past, but it's now deprecated and you shouldn't use it. So stick to 'tax_query'! Using tax_query gives you a lot more flexibility anyway.

Summary

Querying taxonomies is a bit more complicated than categories and tags, as you need to get to grips with the tax_query argument.

However, as we've seen, this is a very powerful argument that gives you a lot of scope and flexibility to query your database in whatever way you wish.

本文WP_Query 参数:分类法(Taxonomies)到此结束。也许上帝让遇见那个适合你的人之前,会遇见很多错误的人,所以当一切发生的时候,你应该心存感激。小编再次感谢大家对我们的支持!

标签: WP_Query Taxonomies