EP026. “WP_Query 自定义查询”
🔒 登录后可标记已读首页「From Our Blogs」区块之前是两张写死的假博客卡片,这一讲用 WP_Query 写第一个自定义查询,把这两张卡片换成真实的「最新 2 篇文章」。顺带讲了一下面向对象的基本概念(class 是蓝图,new 出来的是 object,object 可以用 -> 调用自己的方法),解释为什么 $homepagePosts->have_posts() / $homepagePosts->the_post() 要带着变量名去调用,而不是像默认查询那样直接裸调 have_posts() / the_post()。
涉及文件
wp-content/themes/fictional-university-theme/front-page.php(修改,只改「From Our Blogs」这个区块)
代码实现
只改 full-width-split__two 里「From Our Blogs」标题下方那部分,把两张写死的 event-summary div 换成基于 WP_Query 的 while 循环:
<h2 class="headline headline--small-plus t-center">From Our Blogs</h2>
<?php
$homepagePosts = new WP_Query(array(
'posts_per_page' => 2
));
while ($homepagePosts->have_posts()) {
$homepagePosts->the_post(); ?>
<div class="event-summary">
<a class="event-summary__date event-summary__date--beige t-center" href="<?php the_permalink(); ?>">
<span class="event-summary__month"><?php the_time('M'); ?></span>
<span class="event-summary__day"><?php the_time('d'); ?></span>
</a>
<div class="event-summary__content">
<h5 class="event-summary__title headline headline--tiny"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h5>
<p><?php echo wp_trim_words(get_the_content(), 18); ?> <a href="<?php the_permalink(); ?>" class="nu gray">Read more</a></p>
</div>
</div>
<?php } wp_reset_postdata();
?>
<p class="t-center no-margin"><a href="#" class="btn btn--yellow">View All Blog Posts</a></p>
要点:
new WP_Query(array(...))的参数数组可以传各种筛选条件,这一讲只用了posts_per_page => 2。transcript 里演示过category_name(按分类筛选)和post_type(默认是post,改成page会查页面)这两个参数作为示范,但最终首页代码里只保留了posts_per_page => 2。- 自定义查询的 while 循环不能用裸的
have_posts()/the_post()(那是默认查询专用的),要用$homepagePosts->have_posts()/$homepagePosts->the_post(),通过自己建的这个 object 去调用。 - 摘要文字没有用
the_excerpt(),而是用wp_trim_words(get_the_content(), 18)手动把正文截断到前 18 个单词,效果更可控。get_the_content()是返回值型(不直接输出),所以要包一层echo。 - 循环结束后调用
wp_reset_postdata()是习惯性收尾动作,把 WordPress 全局数据恢复成默认查询该有的状态,避免自定义查询「污染」后面代码对全局 post 数据的判断。不是任何情况下都必须调用(比如已经在模板最底部就无所谓),但养成习惯总是对的。 - 「View All Blog Posts」按钮的
href这一讲还没改,仍是占位符#,留到下一讲。
[截图:前台首页"From Our Blogs"区块,改用 WP_Query 拉取最新 2 篇真实文章后的效果]
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
WP_Query | WP 内建 class | 创建自定义查询的蓝图,new WP_Query(array $args) 生成一个查询对象 |
$query->have_posts() | WP_Query 方法 | 判断这个自定义查询对象是否还有文章要循环 |
$query->the_post() | WP_Query 方法 | 让 WordPress 准备好这个自定义查询里「当前这一篇」的数据 |
wp_trim_words($text, $num_words) | WP 内建 function(返回值,需要 echo) | 把文本截断到指定单词数,常用来做自定义摘要 |
get_the_content() | WP 内建 function(返回值,需要 echo) | 返回当前文章正文内容(不直接输出) |
wp_reset_postdata() | WP 内建 function | 自定义查询循环结束后重置全局 post 数据,恢复成默认查询状态 |
常见坑
- 自定义查询里如果不小心用了裸的
have_posts()/the_post()(没有加上$homepagePosts->),拿到的还是默认查询的数据,在首页这种场景下默认查询只有「Home」这一个页面本身,循环只会跑一次且内容不对。 get_the_content()忘记echo会导致摘要文字不显示。
延伸 / 后续讲座会用到
「View All Blog Posts」按钮的链接、头部导航 Blog 链接的高亮问题会在 EP027 处理,这门课后面章节(自定义文章类型)会大量用到 WP_Query 自定义查询的其他参数。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 6, EP026