15 mins read ‧ 2022/07/19 HEN難
WP Query 輸出指定分類中的置頂文章及一般文章
Table of Contents
前言
最近的一個需求是,業主希望能夠自訂文章的排序 ( 原本按照日期排序 )
希望可以手動置頂
WordPress 原本就有內建置頂的功能,即 sticky post
我原本預期這是個簡單的需求,想不到比平常花了更多時間
需求
一句話講完需求就是:特定分類下的混合Query
- 取出 “指定分類” 裡面的文章,一共取 4 篇出來,預設為時間排序,新→舊
- 如果有置頂文章,置頂文章優先於一般文章
- 如果有多篇置頂文章,則置頂文章也是時間排序,新→舊
置頂文章在後台的設置方法
打勾後,該篇文章就會被設定為置頂
核心思路
- 先用 WP Query 抓出置頂文章
- 再用 WP Query 抓出一般文章 ( 排除置頂文章 )
- 並使用一個計數器,來計算已經輸出多少文章了
WP Query 的實作方式
// 取得置頂的文章ID,是一個 array
$sticky = get_option('sticky_posts');
// 重新排序,讓日期較新的文章ID在前面
rsort($sticky);
// 我們在這裡設置一個計數器,初始值是 0
$count = 0;
// 設定你要抓的分類 id,這邊我們先假設是 45
$catid = 45;
// 第一段 WP Query 開始
$args = array(
'post_type' => 'post', // 選擇 post type
'post__in' => $sticky, // 只抓置頂文章中,符合條件的
// ⭐下方的 'ignore_sticky_posts' 可以不用打,但打了效率比較好
'ignore_sticky_posts' => 1, // 字面意思是是否忽略置頂文章的規則, 1 為 true , 0 為 false,詳細說明底下會說
'cat' => $catid // 抓取特定分類
);
// 上面整段意思就是會從 全部的置頂文章中 , 找出"分類id=45"且"posttype=post"的文章,並且"忽略置頂文章的規則"
// 下面開始就是常規的 WP Query 語句了
$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
while ($the_query->have_posts()) : $the_query->the_post();
// 套用版型
get_template_part('loops/blog');
// 這邊我們讓每篇文章套完版型後,對計數器 $count的值 +1
$count++;
// 如果計數器 $count的值 = 4 就停止迴圈
if ($count == 4) break;
endwhile;
endif;
// 如果計數器已經4篇,那下面就不用執行了
if ($count < 4) {
// 第二段 WP Query 開始
$args = array(
'post_type' => 'post', // 選擇 post type
'posts_per_page' => 4, // 只抓 4 篇,這個可以不用打,但是打了可以限制 Query 數量,效率較好
// ⭐下方的 'ignore_sticky_posts' 這邊必須要打,否則會抓出置頂文章
'ignore_sticky_posts' => 1, // 字面意思是是否忽略置頂文章的規則, 1 為 true , 0 為 false,詳細說明底下會說
'cat' => $catid // 抓取特定分類
);
// 下面開始就是常規的 WP Query 語句了
$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
while ($the_query->have_posts()) : $the_query->the_post();
// 套用版型
get_template_part('loops/blog');
// 這邊我們讓每篇文章套完版型後,對計數器 $count的值 +1
$count++;
// 如果計數器 $count的值 = 4 就停止迴圈
if ($count == 4) break;
endwhile;
endif;
}
核心代碼到這邊其實就已經完成了
ignore_sticky_posts
的含意
⭐ WordPress 置頂文章規則與 🤮坑
WordPress 預設有個 “置頂文章規則”
- 如果你的 WP Query 結果有包含到 “置頂文章” ,則會把置頂文章擺在最前面
- 如果你的 WP Query 結果裡面沒有 “置頂文章” ,那麼 WordPress 會幫你把所有的置頂文章抓出來擺在最前面
🤮這個置頂文章的坑就是,如果你有 “指定分類” 這個置頂文章的規則會失效
不然一開始我以為把 WP Query 的參數設定為這樣子就可以得到我想要的結果
$args = array(
'post_type' => 'post',
'ignore_sticky_posts' => 0,
'cat' => $featured_catid
);
ignore_sticky_posts
的用法
可能的值 | 代表含意 |
---|---|
true / 1 | 忽略/無視上方的”置頂文章規則” |
false / 0 | 預設為false,會使用上方的”置頂文章規則” |
代碼解釋
我們如果回頭看上方的代碼
第一段WP Query
註解說
'ignore_sticky_posts' => 1
可以不用設置,但設置效率會比較高是因為我們已經使用
'post__in' => $sticky
來指定抓出 “置頂文章” sticky post 了,所以不需要再跑 “置頂文章規則”設置
'ignore_sticky_posts' => 1
可以跳過 “置頂文章規則” 提高運行效率
第二段WP Query
註解說
'ignore_sticky_posts' => 1
必須要設置是因為我們原本的 WP Query 目的是要抓出一般文章 ( 非置頂文章 )
但是 “置頂文章規則”2 是,當你的 WP Query 沒抓到 “置頂文章” ,會把所有的 “置頂文章” 都抓出來顯示
很顯然這不是我們要的結果,因此要設置設置
'ignore_sticky_posts' => 1
來跳過 “置頂文章規則”
覺得不錯的話,請給我點個推薦
您的支持與鼓勵是我們前進的最大動力!