
WordPress 有「置頂文章」的功能,但很多人設定之後才發現:置頂只在首頁的文章列表有效,點進分類頁或標籤頁,置頂的文章還是照日期排在原本的位置。
例如你想讓「WordPress 教學」分類的讀者,一進來就先看到一篇入門指南,就需要自己加一段程式碼。
為什麼分類頁不會置頂?
WordPress 核心只在「文章首頁」(is_home())的第一頁處理置頂文章,分類頁、標籤頁、日期彙整頁都不會。所以要自己告訴 WordPress:在分類頁和標籤頁,也把置頂文章排到最前面。
先把文章設為置頂
- 編輯文章時,在右側的文章設定裡勾選「置頂」的選項。
- 或到「文章 → 所有文章」,在文章上按「快速編輯」,勾選置頂。
程式碼:分類頁、標籤頁也置頂
做法分成三步:
- 找出「屬於目前這個分類或標籤」的置頂文章。
- 用
pre_get_posts把它們從原本的文章列表排除,避免重複出現。 - 用
the_posts在第一頁的最前面把它們加回去。
程式碼加在子主題的 functions.php,或用 Code Snippets 外掛新增(說明請看 WordPress functions.php 實用程式碼整理):
PHP
/**
* 取得「屬於目前分類或標籤」的置頂文章 ID
*/
function ahwei_term_sticky_ids( $term ) {
static $cache = array();
$sticky = get_option( 'sticky_posts' );
if ( ! ( $term instanceof WP_Term ) || empty( $sticky ) ) {
return array();
}
if ( ! isset( $cache[ $term->term_id ] ) ) {
$cache[ $term->term_id ] = get_posts( array(
'post__in' => $sticky,
'post_type' => 'post',
'posts_per_page' => -1,
'fields' => 'ids',
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => $term->taxonomy,
'field' => 'term_id',
'terms' => $term->term_id,
),
),
) );
}
return $cache[ $term->term_id ];
}
/**
* 是不是要處理的查詢:前台、主要查詢、分類頁或標籤頁、不是 RSS
*/
function ahwei_is_term_archive_query( $query ) {
return ! is_admin()
&& $query->is_main_query()
&& ( $query->is_category() || $query->is_tag() )
&& ! $query->is_feed();
}
// 1) 從原本的列表排除置頂文章,避免重複出現
add_action( 'pre_get_posts', function ( $query ) {
if ( ! ahwei_is_term_archive_query( $query ) ) {
return;
}
$ids = ahwei_term_sticky_ids( $query->get_queried_object() );
if ( $ids ) {
$query->set( 'post__not_in', array_merge( (array) $query->get( 'post__not_in' ), $ids ) );
}
} );
// 2) 在第一頁的最前面加回置頂文章
add_filter( 'the_posts', function ( $posts, $query ) {
if ( ! ahwei_is_term_archive_query( $query ) || $query->is_paged() ) {
return $posts;
}
$ids = ahwei_term_sticky_ids( $query->get_queried_object() );
if ( ! $ids ) {
return $posts;
}
$stickies = get_posts( array(
'post__in' => $ids,
'orderby' => 'post__in',
'posts_per_page' => count( $ids ),
'ignore_sticky_posts' => true,
) );
return array_merge( $stickies, $posts );
}, 10, 2 );這段程式的行為:
- 只有屬於這個分類或標籤的置頂文章會出現。子分類的文章也算在上層分類裡,跟分類頁本身的規則一樣。
- 只在第一頁置頂,第二頁以後不會再出現,也不會跟一般文章重複。
- 第一頁的文章數會是「置頂篇數+每頁篇數」,例如每頁 10 篇、置頂 2 篇,第一頁會有 12 篇。
- 首頁、RSS、後台都不受影響。
- 傳統主題,或區塊主題裡沿用範本查詢的「文章查詢迴圈」區塊,都適用。
幫置頂文章加上樣式
WordPress 只有在首頁才會幫置頂文章加上 sticky 這個 class,分類頁不會。加上這段,分類頁、標籤頁的置頂文章也會有 sticky class:
PHP
add_filter( 'post_class', function ( $classes, $class, $post_id ) {
if ( ( is_category() || is_tag() ) && ! is_paged() && is_sticky( $post_id ) && ! in_array( 'sticky', $classes, true ) ) {
$classes[] = 'sticky';
}
return $classes;
}, 10, 3 );再用 CSS 讓它醒目一點:
CSS
.category .type-post.sticky,
.tag .type-post.sticky {
border-left: 4px solid #e67e22;
padding-left: 1em;
}傳統主題也可以在列表的範本裡,於標題旁邊加上「置頂」小標籤:
PHP
<?php if ( is_sticky() ) : ?>
<span class="sticky-badge">置頂</span>
<?php endif; ?>舊版程式碼為什麼換掉?
這篇文章舊版的程式碼只用一個 the_posts filter,自己逐一比對分類、標籤、年份、月份、作者,程式很長、不好維護;判斷分類時也沒有把子分類算進去。新的寫法用 pre_get_posts 把排除的工作交給 WordPress 的查詢處理,程式短很多,也不會在第二頁以後重複出現。
不寫程式的做法
- 區塊主題的「文章查詢迴圈」:如果是自己在頁面上放的文章查詢迴圈區塊(沒有沿用範本的查詢),區塊設定裡通常可以選擇置頂文章要包含、排除,或只顯示置頂文章。
- 在分類說明放精選文章:到「文章 → 分類」編輯分類的「內容說明」,放上幾篇推薦文章的連結。主題有顯示分類說明的話,就會出現在分類頁上方。
延伸閱讀
分類頁整理得好,讀者一進來就能找到最重要的文章。正威網路行銷是 25 年經驗的基隆網頁設計工作室,也服務台北與全台客戶,提供客製化網頁設計與 SEO 搜尋引擎優化,歡迎來聊聊。







發表留言
還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。