在 WordPress 中,熟练使用WP_Query,可以允许我们非常自由地指定要检索的帖子。毫不夸张地说,WP_Query是WordPress 中的必备知识。
目录
WP_Query 子循环的基本用法
如何知道检索到的帖子数
指定特定的帖子页面/固定页面
日期说明
与类别、标签和分类法相关的参数
自定义字段的参数
指定多个键和值的模式
其他参数
具体例子等
但是,WP_Query 子循环用途广泛,需要学习的东西太多了!
因此,我们整理了一下参数以及如何使用它们的方法。
WP_Query 子循环的基本用法
暂时先从使用WP_Query的子循环的基本用法说起。我总是复制并粘贴它,然后再修改它的参数。
子循环轮廓的模板代码
<?php
//设定$args
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'no_found_rows' => true, //使用分页表示时,false。
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
while ($the_query->have_posts()) : $the_query->the_post();
/*反复循环 */
endwhile;
endif;
wp_reset_postdata();
?>
大体流程如下。
- 指定检索数组
$args
中文章的条件。 - 放入信息并调用WP_Query Class以获取查询信息和循环。
wp_reset_postdata()
一定要在最后重置子循环中正在检索的post信息,以免影响主循环。
注意!
wp_reset_postdata()wp_reset_query()
小心不要与混淆。
后者是在query_posts()
中使用覆盖主查询时重置的功能。
如何知道检索到的帖子数
如何检查使用 WP_Query 检索了多少帖子。
获取帖子数
$the_query = new WP_Query($args);
$post_count = $the_query->post_count; //在当前的页面中检索了多少帖子。
$found_posts = $the_query->found_posts; //符合条件的所有帖子。
你可以得到上面的帖子数。
$the_query->post_count
的值'posts_per_page'
是 指定的最大值。
$the_query->found_posts
当'no_found_rows'
为true时,值始终为 0。
基本参数
这是主要问题。我们可在传递给 WP_Query 的条件数组$args
中使用的参数。
指定 SQL 查询选项
‘no_found_rows’ (bool)
‘no_found_rows’ (bool) | 是否避免执行检查项目总数的 SQL 函数。 如果指定是[ true] ,SQL查询SQL_CALC_FOUND_ROWS 就不会被附加,检索所有记录的无用SQL问题将减少一个。在pager的处理意外,请指定[true],这样显示速度会更快。 |
指定帖子类型
如何指定帖子类型和状态。
‘post_type’ (string / array)
指定帖子类型。默认值为'post'
。如果要指定多个,可以在数组中指定。
如果在查询中使用’tax_query’,那么默认值是’any’。
可以指定的值如下。
‘post’ | 帖子 |
---|---|
‘page’ | 固定页面 |
‘revision’ | 历史(修订) |
‘attachmen’ | 附件。 注意,附件默认为 ‘inherit’,除非在后述参数’post_status中明确的设定’inherit’或者’any’,否则无法获取附件。 |
‘pnav_menu_item’ | 导航菜单项 |
‘any’ | 包括,除版本和’exclude_from_search’参数设置为true 的类型之外,的所有类型。 |
‘自定义帖子类型‘ | 任何自定义帖子类型名称 |
帖子类型规范示例
$args = array(
'post_type' => 'page', //固定页面取得
/* ...其他属性... */
);
指定特定的帖子页面/固定页面
如何指定特定帖子(包括自定义帖子)和固定页面。
‘p’ (int) | 指定帖子 ID。 |
‘title’ (string) | 指定帖子的标题。 |
‘name’ (string) | 指定 post slug。 |
‘page_id’ (int) | 指定静态页面 ID。 |
‘pagename’ (string) | 指定固定页面的 slug。 要显示子页面,请指定由正斜杠分隔的父项和子项。 |
‘post_parent’ (int) | 指定固定页面的父 ID。返回子页面。 |
‘post__in’ (array) | 在数组中指定多个帖子 ID。 |
‘post__not_in’ (array) | 在数组中指定要忽略的帖子 ID。 |
为每个属性复制粘贴代码
$args = array(
'p' => 10, //指定帖子 ID
'name' => 'post-slug', //指定 post slug
'page_id' => 20, //指定静态页面 ID
'pagename' => 'page-slug', //指定固定页面的 slug
'post_parent' => 30, //指定固定页面的父 ID
'post__in' => array(5, 8, 11), //在数组中指定多个帖子 ID
'post__not_in' => array(3, 6), //在数组中指定要忽略的帖子 ID
);
指定排序顺序
如何指定检索到的文章的显示顺序(循环顺序)。
‘order’ (‘ASC’ / ‘DESC’)
指定是按升序还是降序排序(默认为降序'DESC' )。 | |
‘ASC’ | 从最低到最高( 1, 2, 3), (a, b, c) |
‘DESC’ | 从最高到最低(3, 2, 1), (c, b, a) |
‘orderby’ (string / array)
按此参数中指定的项目的值对检索到的帖子进行排序。默认’date’为 ,按日期获取。可以指定的值如下。 | |
‘none’ | 无序的 |
‘ID’ | 按帖子 ID排序 |
‘author’ | 按作者排序 |
‘title’ | 按标题排序 |
‘date’ | 按日期排序 |
‘modified’ | 按更新日期排序 |
‘parent’ | 按帖子/页面的父 ID排序 |
‘rand’ | 随机排序 |
‘comment_count’ | 按评论数排序 |
‘menu_order’ | 按管理屏幕上的显示顺序排序。 页面、自定义帖子排序插件等使用的值 (每页的默认值为 0 ) |
‘meta_value’ | 按自定义字段值排序。’meta_key=keyname’必须出现在查询中。请注意, 排序顺序是 string order 。 |
‘meta_value_num’ | 按数字对自定义字段进行排序。’meta_key=keyname’必须出现在查询中。 |
‘post__in’ | ‘post__in’按参数数组中列出的帖子 ID 排序 |
为每个属性复制粘贴代码
$args = array(
'order' => 'ASC', //指定升序或者降序
'orderby' => 'rand' //指定条件
);
这些在下面按顺序描述。
指定每页的帖子数量,以及转送页数。
关于如何指定每页的帖子数量和与page feed相关的参数。
‘posts_per_page’ (int) | 要包含在一页上的帖子数。’posts_per_page’ => -1获取所有帖子。 使用分页时用这个参数’paged’指定一个参数。 |
‘posts_per_archive_page’ (int) | 要包含在一页上的帖子数。仅适用于存档页面。如果is_archive()或者is_search()为 true的页面,优先于’posts_per_page”showposts’的值。 |
‘paged’ (int) | 指定获取哪一页信息。基本上,通过指定当前页get_query_var(‘paged’)的值来使用它。请注意,即使不使用分页,也可以使用此参数。 |
‘offset’ (int) | 要转移(跳过)的帖子数。 注意:如果蛇者’offset’参数,那么’paged’参数将被忽略该。因此它不被分页。另请注意,’posts_per_page’参数为 -1时忽略此参数。 |
‘nopaging’ (bool) | 显示所有帖子或使用分页。默认值为’false’(使用分页)。 |
‘page’ (int) | 静态首页的页码。显示将出现在静态首页的第 X 页上的帖子。 |
‘ignore_sticky_posts’ (bool) | 是否忽略置顶贴的优先级。默认’false’为 ,按原样显示在顶部。如果设置为’true’ ,它将被视为普通页面而不是顶部。 |
为每个属性复制粘贴代码
/* 获取当前的页数*/
$paged = get_query_var('paged') ?: 1; //头页的默认值是0,所以我们把它改为1.
// $paged = get_query_var('page') ?: 1; //如果frontpage是固定页面的情况。
$args = array(
'posts_per_page' => 10, //指定要获取的帖子数量。
'posts_per_archive_page' => 20, //指定要获取的历史帖子数量
'paged' => $paged, //指定当前的页数。
'offset' => 3, //指定忽略页页数。
'nopaging' => false, //否定向前送页。
'ignore_sticky_posts' => false //忽略固定页面。
);
※get_query_var( 'page' )
使用 ‘page’ 而不是 ‘paged’来支持为静态首页指定的页面模板中的分页。
查询变量'page'
在其内容中包含快速标签,并保存单个分页帖子或页面的页码。
日期说明
如何指定日期和时间参数。
‘year’ (int) | 年份(4 位数字,例如 2017) |
‘monthnum’ (int) | 月 (1-12) |
‘w’ (int) | 一年中的周数 ( 0-53 )。使用 MySQL 的 WEEK 命令。 get_option(“start_of_week”)取决于价值 |
‘day’ (int) | 天(1 到 31) |
‘hour’ (int) | 小时 (0-23) |
‘minute’ (int) | 分钟 (0-60) |
‘second’ (int) | 秒(0-60) |
‘m’ (int) | 按年份和月份指定。(例如:201706) |
为每个属性复制粘贴代码
args = array(
'year' => 2017, //指定年份
'mouthnum' => 6, //指定月份
'w' => 6, //指定周
'day' => 14, //指定天
'hour' => 20, //指定时间
'minute' => 0, //指定分钟
'second' => 0, //指定秒
'm' => 201706 //指定年和月
);
可以更复杂地指定的’date_query’属性。请大家查询相关的资料。
指定发布状态
如何指定帖子状态。
‘post_status’ (string / array)
指定发布状态。默认值为’publish’。 但是,如果用户在登录状态,’private’是它的默认值。可以指定的值如下。 | |
‘publish’ | 发布的帖子或页面 |
‘pending’ | 帖子待审 |
‘draft’ | 草稿帖 |
‘auto-draft’ | 新创建的帖子没有内容 |
‘future’ | 预定帖子 |
‘private’ | 非登录用户看不到帖子 |
‘inherit’ | 修订 |
‘trash’ | 垃圾箱中的帖子 |
‘any’ | 除“垃圾”和“自动草稿”外的所有状态的帖子 |
指定帖子状态的示例
$args = array(
'post_status' => 'publish', //获取已经发布的帖子。
/* ..其他属性... */
);
与类别、标签和分类法相关的参数
类别指定
如何为类别指定参数。
描述示例
$args = array(
'cat' => 5,
'category_name' => 'info, author',
'category__and' => array( 1, 6 ), //1和6
'category__in' => array( 1, 6 ), //1或者6
'category__not_in' => array( 2, 4 ) //2,4除外
);
‘cat’ (int) | 指定类别 ID。如果要省略它,- 请用(减号)指定它。 |
‘category_name’ (string) | 指定类别别名。您可以, 通过指定【,】分隔符来获取其中任何一个的帖子,并通过指定【+】分隔符来获取所有这些帖子。 |
‘category__and’ (array) | 将类别 ID 指定为数组。您可以获得包含具有指定 ID 的所有类别的帖子。 |
‘category__in’ (array) | 将类别 ID 指定为数组。您可以获得包含具有指定 ID 的任何类别的帖子。 |
‘category__not_in’ (array) | 将类别 ID 指定为数组。您可以获得不包含具有指定 ID 的类别的帖子。 |
指定标签
如何为标签指定参数。
描述示例
$args = array(
'tag_id' => 5,
'tag' => 'html+css',
'tag__and' => array( 1, 6 ),
'tag__in' => array( 1, 6 ),
'tag__not_in' => array( 1, 6 ),
'tag_slug__and'=> array( 'html', 'css' ),
'tag_slug__in'=> array( 'html', 'css' )
);
‘tag_id’ (int) | 指定标记 ID。如果要省略它,-请用(减号)指定它。 |
‘tag’ (string) | 指定标签块。您可以通过指定【,】分隔符来获取其中 任何一个的帖子。 |
‘tag__and’ (array) | 将标记 ID 指定为数组。您可以获得包含具有指定 ID 的所有标签的帖子。 |
‘tag__in’ (array) | 将标记 ID 指定为数组。您可以获得包含具有指定 ID 的任何标签的帖子。 |
‘tag__not_in’ (array) | 将标记 ID 指定为数组。您可以获得不包含具有指定 ID 的标签的帖子。 |
‘tag_slug__and’ (array) | 将标签 slug 指定为数组。您可以获得包含具有指定 slug 的所有标签的帖子。 |
‘tag_slug__in’ (array) | 将标记 ID 指定为数组。您可以获得包含具有指定 ID 的所有标签的帖子。 |
指定分类
如何指定分类法的参数。
描述示例
$args = array(
'tax_query' => array( //指定分类
'relation' => 'AND', //指定条件的关系
//条件1
array(
'taxonomy' => 'music', //指定分类的名字
'field' => 'id', //用id或者有哪个slug来指定
'terms' => array(102, 114, 235), //用id来指定Term('field'或者'id')
'operator' => 'AND', //指定'terms'的关系
'include_children' => false, //是否包含字分类
),
//条件2
array(
'taxonomy' => 'movie',
'field' => 'slug',
'terms' => 'action', //用id来指定Term('field'或者'id')
)
)
);
‘tax_query’ (array) | 总结分类法参数的数组。 ‘tax_query’每个参数在数组中进一步指定为 的值。 |
‘taxonomy’ (string) | 指定分类法。 |
‘field’ (‘id’ / ‘slug’) | 声明是否通过 ID 或 slug 指定术语。 |
‘terms’ (int / string / array) | 指定术语。是通过 ID 指定还是通过 slug 指定,’field’取决于参数中的声明。多个规格时,在数组中指定。 |
‘operator’ (‘AND’ / ‘IN’ / ‘NOT IN’) | 可以指定是否获取包含所有指定术语的帖子( ‘AND’)、包含其中任何术语的帖子 ( ‘IN’) 或不包含( ‘NOT IN’)的帖子。仅当是数组时有效。 |
‘include_children’ (bool) | 如果分类法具有层次结构,是否包括子术语。默认为true。 |
‘relation’ (‘AND’ / ‘OR’) | 在指定与分类法相关的多个参数数组时,指定是获取与所有匹配的帖子( ‘AND’) 还是与其中任何一个匹配的帖子(‘OR’)。 |
自定义字段的参数
有两种指定自定义字段的模式。
指定一个键和一个值的简单模式
模式 1。如果你只是简单地一一指定key和value。
描述示例
//自定义的字段是文字的时候
$args = array(
'meta_key' => 'price',
'meta_value' => '100円',
'meta_compare' => '=',
)
//自定义的字段是数字或者是小数的时候
$args = array(
'meta_key' => 'number',
'meta_value_num' => 100,
'meta_compare' => '>',
)
‘meta_key’(string) | 指定自定义字段的键。 |
‘meta_value’(string) | 指定自定义字段的值。比较为字符串。 |
‘meta_value_num’(number) | 指定自定义字段的值。比较数值。 |
‘meta_compare’(string) | ‘meta_value’的测试运算符。可以使用以下值。 |
※’meta_value’的测试运算符。可以使用以下值。
数据类型 | 意义 | 有效数据类型 |
---|---|---|
‘=’ | 匹配值 | 全部(如果省略) |
‘!=’ | 与值不匹配 | 全部 |
‘>’ | 大于 | 数字系统/日期时间系统 |
‘>=’ | 大于等于 | 数字系统/日期时间系统 |
‘<‘ | 小于 | 数字系统/日期时间系统 |
‘<=’ | 小于等于 | 数字系统/日期时间系统 |
‘LIKE’ | 匹配值指定的字符串 (*与SQL中的“%○○%”相同) | ‘CHAR’ |
‘NOT LIKE’ | 与值指定的字符串不匹配 | CHAR |
‘IN’ | 匹配任何指定的值(数组) | 全部 |
‘NOT IN’ | 不匹配值(数组)指定的任何内容 | 全部 |
‘BETWEEN’ | 在两个值指定的范围内(○以上和○以下) | 数字系统/日期时间系统 |
‘NOT BETWEEN’ | 超出两个值指定的范围 | 数字系统/日期时间系统 |
指定多个键和值的模式
模式二。关于如何使用参数数组指定有关自定义字段的详细信息。
描述示例
$args = array(
'meta_query' => array( //自定义字段的综合Array()
array(
'key' => 'color', //指定自定义字段健。
'value' => array('red','blue'), //指定自定义字段的值
'type' => 'CHAR', //指定自定义字段的型
'compare' => 'IN' //指定对于'value'参数的理论关系
)
)
);
‘meta_query’(array) | 自定义字段参数。将信息放在这个数组中。 |
‘relation’ (‘AND’ / ‘OR’) | 将多个数组放入 meta_query 时的布尔关系。可能的值是’AND’和’OR’(默认是’AND’)。 *仅插入一个数组时请勿使用。 |
‘key’ (string) | 自定义字段的键。 |
‘value’ (string / array) | 自定义字段值。仅当比较为“IN”、“NOT IN”、“BETWEEN”或“NOT BETWEEN”时,才能指定数组。 从 WordPress 3.9 开始,您可以在指定“EXISTS”或“NOT EXISTS”进行比较时省略值。 |
‘type’ (string) | 自定义字段的值类型。可以使用以下值。 |
‘compare’ (string) | 测试操作员。可能的值与模式 1中的 ‘meta_compare’ 相同。 |
自定义字段的值类型。可以使用以下值。
数据类型 | 意义 |
---|---|
‘CHAR’ | 文字 |
‘NUMERIC’ | SIGNED的别名 |
‘DECIMAL’ | 浮点数 |
‘SIGNED’ | 整数(有符号) |
‘UNSIGNED’ | 整数(无符号) |
‘DATE’ | 日期 |
‘DATETIME’ | 日期和时间 |
‘TIME’ | 时间 |
‘BINARY’ | 二进制 |
这’meta_query’,通过嵌套数组可以处理得相当复杂,所以我将介绍一个具体的例子。
同时指定多个条件时的说明示例
$args = array(
'meta_query' => array( //自定义字段的综合Array()
'relation' => 'AND', //AND : 满足条件1,2
//条件1 ( 'color'的自定义字段的健是 'red' 或者是 'blue'的情况 )
array(
'key' => 'color', //指定自定义字段的健
'value' => array('red','blue'), //指定自定义字段的值
'type' => 'CHAR', //指定自定义字段的型
'compare' => 'IN' //IN :指定对于'value'参数的理论关系
),
//条件2 (自定义字段的健'price'的值是小于1000,并且'size'是 'big'的帖子)
array(
'relation' => 'AND', //AND : 满足条件A,B
//满足条件2的条件A (price健的值小于1000)
array(
'key' => 'price',
'value' => 1000,
'type' => 'NUMERIC',
'compare' => '<'
),
//满足条件2的条件B (size健的値是big)
array(
'key' => 'size',
'value' => 'big',
'compare' => '='
)
)
)
);
在这个例子中,你可以得到满足“color为red或blue”和“price小于1000且size=big”的帖子。
其他参数
更详细地指定日期
如何将日期和日期时间参数放入数组并更详细地指定它们。
‘date_query’(array) | 规格复杂的日期参数 |
array->( ‘year’ )(int) | 月 (1-12) |
array->( ‘monthnum’ )(int) | 月 (1-12) |
array( ‘w’ )(int) | 周数 (0-53) |
array( ‘day’ )(int) | 天(1 到 31) |
array( ‘hour’ )(int) | 小时 (0-23) |
array( ‘minute’ )(int) | 分钟 (0-60) |
array( ‘second’ )(int) | 秒(0-60) |
array( ‘after’ )(string / array) | 在此日期之后获取帖子。可以是与 strtotime()兼容的字符串或具有“年”、“月”、“日”值的数组 |
array( ‘before’ )(string / array) | 在此日期之前获取帖子。可以是与 strtotime()兼容的字符串或具有“年”、“月”、“日”值的数组 |
array( ‘inclusive’ )(bool) | 是否准确地包括之后和之前的指定日期。 |
array( ‘compare’ )(string) | 仅供参考:请参阅WP_Date_Query::get_compare() 。 |
array( ‘colum’ )(string) | 要查询的列(wp_posts 表)。默认为“post_date”。 |
array( ‘relation’ )(‘OR’ / ‘AND’) | 如何组合和比较子数组。默认为 AND。 |
作者的指定
如何指定与用户关联的帖子。
‘author’(int) | 用户 ID(用 – 省略) |
‘author_name’(string) | 用户名 ( user_nicename )。不是性别,名字,昵称 |
‘author__in’(array) | 由用户 ID 指定。可以指定多个。 |
‘author__not_in’(array) | 由用户 ID 指定。省略指定贡献者 |
指定密码
从 3.9 版开始,您可以指定密码状态。
‘has_password’(bool) | 指定 true 以显示受密码保护的帖子,指定 false 以显示不受保护的帖子。如果要显示是否有密码,请指定 null(默认)。 |
‘post_password’(string) | 查看受特定密码保护的帖子。 |
搜索规范
指定用于搜索功能的参数
‘s’(string) | 指定要搜索的关键字。用于search.php等 |
指定权限
如果用户具有适当的权限,则可以查看私人文章和已发布的帖子。
‘perm’(‘readable’ / ‘editable’) | 指定用户权限(可读或可编辑)。 |
指定缓存
您可以防止将检索到的数据添加到缓存中。
‘cache_results’(bool) | 如何缓存帖子信息。false禁止 |
‘update_post_meta_cache’(bool) | 如何缓存帖子元信息(例如自定义字段)。false禁止 |
‘update_post_term_cache’(bool) | 如何缓存后期信息(类别等)。false禁止 |
指定返回值
指定返回值。
‘fields’(string)
指定要返回的字段。指定除以下两个之外的任何内容以返回所有字段(默认)
‘ids’ | 返回一个帖子 ID 数组 |
‘id=>parent’ | 返回一个 stdClass 对象数组,其属性为 ID(post ID)和 post_parent(parent’s ID) |
具体例子等
循环内使用的关键信息
将循环中经常使用的文章标题和发布日期存储在变量中很方便。
//在循环之前指定以下的变量,会很方便
$title = esc_html(get_the_title()); //帖子的标题
$url = esc_url(get_permalink()); //帖子的URL
$date = get_the_time('Y/m/d'); //帖子的创作日期
$modify = get_the_modified_date('Y/m/d'); //帖子的更新日
$category = get_the_category(); //帖子的分类
$tags = get_the_tags(); //帖子的标签
$content = mb_substr(esc_html(get_the_content()),0,60)."..."; //帖子的文本
//帖子的图标URL
if(has_post_thumbnail()):
$src = get_thumb_src('尺寸');
else:
$src = "默认图标的途径";
endif;
使用pager时的描述示例(使用 WP_pagenavi 时)
//设置当前页
$paged = get_query_var('paged')? get_query_var('paged') : 1;
$args = array(
//参数...
'paged' => $paged,
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
while ($the_query->have_posts()) : $the_query->the_post();
//循环
endwhile;
endif;
//wp_pagenavi的描述
wp_pagenavi(array('query'=>$the_query));
wp_reset_postdata();