WordPress源码深度解析之:`WordPress`的`WP_Term_Query`:如何查询分类法和标签。

各位观众老爷,晚上好!我是你们的老朋友,今天咱来聊聊WordPress里一个挺重要的角色——WP_Term_Query,它就像一个高级侦探,专门负责在你的分类法(Taxonomy)和标签(Tag)世界里搜寻你想要的东西。

开场白:分类法和标签,网站的“分类员”

在开始之前,咱得先简单回顾一下分类法和标签。它们就好比图书馆里的图书管理员,负责将各种书籍(文章)按照主题、作者、类型等进行分类。

  • 分类法 (Taxonomy):这是个比较宽泛的概念,它定义了文章的分类方式。WordPress默认提供两种分类法:
    • Category (分类目录):通常用于对文章进行主题性的分类,比如“新闻”、“技术”、“美食”等等。
    • Tag (标签):标签则更灵活,可以用来描述文章的细节特征,比如“WordPress”、“PHP”、“优化”等等。
  • 自定义分类法 (Custom Taxonomy):WordPress还允许你创建自己的分类法,例如“书籍类型”、“产品颜色”等等,以满足更个性化的需求。

WP_Term_Query闪亮登场

WP_Term_Query是WordPress提供的用于查询分类法和标签的类。 它允许你根据各种条件(名称、ID、slug、父级等等)来检索你需要的分类法和标签。 就像一个数据库查询构造器,它帮你构建复杂的查询,然后从数据库中获取结果。

基本用法:来个简单的例子

咱们先从一个简单的例子开始,看看WP_Term_Query是怎么工作的。

<?php

// 1. 构建查询参数数组
$args = array(
    'taxonomy' => 'category', // 指定分类法
    'hide_empty' => false, // 是否隐藏空分类(没有文章的分类)
    'number' => 5, // 返回多少个
);

// 2. 创建 WP_Term_Query 对象
$term_query = new WP_Term_Query( $args );

// 3. 执行查询
if ( ! empty( $term_query->terms ) ) {

    // 4. 循环遍历结果
    foreach ( $term_query->terms as $term ) {
        echo '<p>分类名称: ' . esc_html( $term->name ) . '</p>';
        echo '<p>分类链接: ' . esc_url( get_term_link( $term ) ) . '</p>';
    }
} else {
    echo '<p>没有找到分类。</p>';
}

?>

这段代码做了什么?

  1. 构建查询参数数组: $args 数组定义了查询的条件。 taxonomy 指定了我们要查询的分类法,这里是 category(分类目录)。 hide_empty 设置为 false 表示我们也要显示空的分类。 number 设置为 5 表示我们最多返回 5 个分类。
  2. 创建 WP_Term_Query 对象: 我们使用 $args 数组创建了一个 WP_Term_Query 对象。 这个对象会根据我们的参数构建 SQL 查询。
  3. 执行查询: $term_query->terms 包含了查询结果。 如果结果不为空,就说明我们找到了分类。
  4. 循环遍历结果: 我们使用 foreach 循环遍历 $term_query->terms 数组,并输出每个分类的名称和链接。

查询参数:$args 数组的各种姿势

$args 数组是 WP_Term_Query 的灵魂所在,它决定了你的查询行为。 下面是一些常用的查询参数:

参数名 类型 描述 默认值
taxonomy string/array 要查询的分类法名称。 可以是单个字符串(例如 ‘category’)或一个字符串数组(例如 array( 'category', 'post_tag' ))。
object_ids array 只返回与给定文章ID关联的分类法术语。
search string 搜索符合给定搜索词的术语。
name string/array 按名称查找术语。 可以是单个名称或一个名称数组。
slug string/array 按别名(slug)查找术语。 可以是单个别名或一个别名数组。
term_id int/array 按ID查找术语。 可以是单个ID或一个ID数组。
term_taxonomy_id int/array 按 term_taxonomy_id 查找。
parent int 只返回给定父级ID的术语。
child_of int 只返回给定ID的术语的子级术语。
hide_empty bool 是否隐藏空术语(没有文章关联的术语)。 true
hierarchical bool 是否返回分层结构的结果。 对于非分层分类法(例如标签),此参数将被忽略。 true
number int 返回多少个术语。 设置为 0'' 表示返回所有术语。 ''
offset int 从第几个术语开始返回。 用于分页。 0
orderby string 排序方式。 可选值:name(名称)、slug(别名)、term_id(ID)、count(文章数量)、term_groupnone name
order string 排序顺序。 可选值:ASC(升序)、DESC(降序)。 ASC
meta_key string 用于排序的自定义字段的键名。 必须与 orderby 参数一起使用。
meta_value mixed 用于过滤的自定义字段的值。 必须与 meta_key 参数一起使用。
meta_query array 用于进行更复杂的自定义字段查询。
update_term_meta_cache bool 是否更新术语元数据缓存。 设置为 false 可以提高性能,但可能导致元数据不是最新的。 true
count bool 是否返回术语的文章数量。 默认为true。 true
lang string 指定语言。 需要安装多语言插件如WPML。

高级用法:各种花式查询

现在,让我们看看一些更高级的用法,让你能更灵活地使用 WP_Term_Query

  1. 按别名 (Slug) 查询:
$args = array(
    'taxonomy' => 'post_tag',
    'slug' => 'wordpress-plugin', // 查询别名为 "wordpress-plugin" 的标签
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    $tag = $term_query->terms[0]; // 获取第一个结果
    echo '<p>标签名称: ' . esc_html( $tag->name ) . '</p>';
} else {
    echo '<p>未找到标签。</p>';
}
  1. 按名称 (Name) 查询:
$args = array(
    'taxonomy' => 'category',
    'name' => '新闻', // 查询名称为 "新闻" 的分类
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    $category = $term_query->terms[0];
    echo '<p>分类名称: ' . esc_html( $category->name ) . '</p>';
} else {
    echo '<p>未找到分类。</p>';
}
  1. 查询多个分类法:
$args = array(
    'taxonomy' => array( 'category', 'post_tag' ), // 查询分类和标签
    'number' => 10,
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    foreach ( $term_query->terms as $term ) {
        echo '<p>名称: ' . esc_html( $term->name ) . '</p>';
        echo '<p>分类法: ' . esc_html( $term->taxonomy ) . '</p>'; // 输出分类法名称
    }
} else {
    echo '<p>未找到任何分类或标签。</p>';
}
  1. 使用 meta_query 进行自定义字段查询:

假设你的分类法有一个名为 color 的自定义字段,你想查询所有 color 值为 "red" 的分类。

$args = array(
    'taxonomy' => 'category',
    'meta_query' => array(
        array(
            'key' => 'color', // 自定义字段键名
            'value' => 'red', // 期望的值
            'compare' => '=', // 比较运算符,这里是等于
        ),
    ),
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    foreach ( $term_query->terms as $term ) {
        echo '<p>分类名称: ' . esc_html( $term->name ) . '</p>';
    }
} else {
    echo '<p>未找到符合条件的分类。</p>';
}
  1. 结合 object_ids 查询文章关联的分类:

假设你想获取 ID 为 123 的文章的所有分类。

$args = array(
    'taxonomy' => 'category',
    'object_ids' => 123, // 文章 ID
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    foreach ( $term_query->terms as $term ) {
        echo '<p>分类名称: ' . esc_html( $term->name ) . '</p>';
    }
} else {
    echo '<p>该文章没有关联任何分类。</p>';
}
  1. 分页查询:
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1; // 获取当前页码
$per_page = 10; // 每页显示多少个

$args = array(
    'taxonomy' => 'category',
    'number' => $per_page,
    'offset' => ( $paged - 1 ) * $per_page, // 计算偏移量
);

$term_query = new WP_Term_Query( $args );

if ( ! empty( $term_query->terms ) ) {
    foreach ( $term_query->terms as $term ) {
        echo '<p>分类名称: ' . esc_html( $term->name ) . '</p>';
    }

    // 显示分页链接
    $total_terms = wp_count_terms( 'category' ); // 获取总共有多少个分类
    $total_pages = ceil( $total_terms / $per_page ); // 计算总共有多少页

    echo paginate_links( array(
        'base' => get_pagenum_link( 1 ) . '%_%',
        'format' => '/page/%#%',
        'current' => $paged,
        'total' => $total_pages,
    ) );

} else {
    echo '<p>没有找到分类。</p>';
}

性能优化小贴士

虽然 WP_Term_Query 非常强大,但如果不注意,也可能影响网站的性能。 这里有一些优化建议:

  • 尽量使用明确的查询条件: 避免使用过于宽泛的查询,例如不指定 taxonomy 就查询所有术语。
  • 合理使用缓存: WordPress 已经对分类法和标签进行了缓存,但如果你的查询非常复杂,可以考虑使用 Transient API 或其他缓存机制来缓存查询结果。
  • 谨慎使用 meta_query 自定义字段查询通常比标准字段查询更耗费资源。
  • 避免在循环中进行查询: 尽量一次性获取所有需要的数据,而不是在循环中多次查询。

WP_Term_Query的返回值和属性

当你创建并执行了 WP_Term_Query 对象后,你可以通过以下属性访问查询结果:

  • $term_query->terms:这是一个包含查询结果的 WP_Term 对象数组。 每个 WP_Term 对象代表一个分类法术语。
  • $term_query->term_count:返回查询到的术语数量。
  • $term_query->query_vars:返回传递给 WP_Term_Query 构造函数的参数数组。
  • $term_query->request:返回实际执行的 SQL 查询语句。 调试时很有用。

WP_Term 对象

WP_Term 对象包含了分类法术语的所有信息,例如:

  • term_id:术语ID。
  • name:术语名称。
  • slug:术语别名。
  • term_group:术语组。
  • term_taxonomy_id:术语分类ID。
  • taxonomy:分类法名称。
  • description:术语描述。
  • parent:父级术语ID。
  • count:与该术语关联的文章数量。
  • filter:过滤器。

你可以通过 $term->property_name 的方式访问这些属性。

总结

WP_Term_Query 是一个功能强大的工具,可以让你轻松地查询和管理 WordPress 的分类法和标签。 掌握了它的用法,你就可以构建更灵活、更强大的 WordPress 主题和插件。 记住,优化查询是提高网站性能的关键。

好了,今天的讲座就到这里。 感谢各位的观看! 如果有什么问题,欢迎随时提问。 我们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注