WP DEVELOP

EP026. “WP_Query 自定义查询”

首页 WordPress 开发课程 BLOG · EP026
约 10 分钟· #EP026#BLOG
🔒 登录后可标记已读

首页「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_QueryWP 内建 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