Custom Post Type (CPT) 讓 WordPress 不只管理文章與頁面,也能管理課程、作品、商品、活動、師資等自訂內容。本章介紹 CPT 的適用情境與外掛實作方式。
本章學習目標
能判斷何時需要 Custom Post Type,並使用外掛註冊自訂內容類型與基本前台顯示。
14.1 自定義貼文類型應用之外掛介紹
如果某類資料有自己的欄位、列表、分類或網址結構,就適合使用 CPT。例如「課程」可能有授課教師、週次、難度與教材連結,與一般文章不同。
CPT 與分類法
CPT 定義內容類型,Taxonomy 定義分類方式。例如 course 是內容類型,而「難度」、「主題」、「學期」可以是分類法。
什麼時候不需要 CPT
不是所有資料都需要 CPT。如果只是一般教學文章,用分類與標籤即可;如果只是頁面中的一段固定內容,也不需要建立新的內容類型。CPT 適合「有一批同類型資料,需要獨立管理、查詢與呈現」的情境。
- 適合 CPT:課程、商品、作品、活動、師資、出版品。
- 不一定需要 CPT:網站簡介、單一聯絡資訊、首頁區塊文案。
CPT、欄位與分類的分工
設計資料模型時,可以用三個問題拆解:
- 這是什麼種類的內容?如果答案是「課程」,它可能是 CPT。
- 它需要哪些屬性?例如教師、週次、時數,這些可能是 meta fields。
- 它如何被分組?例如難度、主題、學期,這些可能是 taxonomy。
14.2 在外掛中建立 Custom Post Type
add_action('init', 'wp2026_register_course_cpt');
function wp2026_register_course_cpt() {
register_post_type('course', [
'labels' => [
'name' => '課程',
'singular_name' => '課程',
],
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-welcome-learn-more',
'supports' => ['title', 'editor', 'thumbnail', 'excerpt'],
'show_in_rest' => true,
]);
}
重要參數說明
public:是否可在前台查詢與顯示。has_archive:是否有封存列表頁。rewrite:設定網址 slug。supports:後台編輯器支援哪些功能。show_in_rest:是否支援區塊編輯器與 REST API。menu_icon:後台選單圖示。
'rewrite' => ['slug' => 'courses'],
'supports' => ['title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'],
網址與重新整理固定網址
新增 CPT 後若前台出現 404,通常需要到「設定 → 固定網址」按儲存,讓 WordPress 重新產生 rewrite rules。
正式外掛可在啟用時呼叫 flush_rewrite_rules(),但不要在每次頁面載入時呼叫,否則會影響效能。
register_activation_hook(__FILE__, 'wp2026_activate');
function wp2026_activate() {
wp2026_register_course_cpt();
flush_rewrite_rules();
}
註冊自訂分類法
以下範例替課程建立「課程難度」分類法:
add_action('init', 'wp2026_register_course_taxonomy');
function wp2026_register_course_taxonomy() {
register_taxonomy('course_level', ['course'], [
'labels' => ['name' => '課程難度'],
'public' => true,
'hierarchical' => true,
'show_in_rest' => true,
'rewrite' => ['slug' => 'course-level'],
]);
}
新增課程自訂欄位
課程常需要教師、時數、教材網址等欄位。可以先用 meta box 實作,理解資料儲存流程。
add_action('add_meta_boxes', 'wp2026_add_course_meta_box');
function wp2026_add_course_meta_box() {
add_meta_box(
'wp2026_course_info',
'課程資訊',
'wp2026_render_course_meta_box',
'course'
);
}
function wp2026_save_course_meta($post_id) {
if (!current_user_can('edit_post', $post_id)) {
return;
}
$hours = isset($_POST['wp2026_hours']) ? absint($_POST['wp2026_hours']) : 0;
update_post_meta($post_id, '_wp2026_hours', $hours);
}
add_action('save_post_course', 'wp2026_save_course_meta');
模板檔案
若 CPT 名稱是 course,可在主題中建立 archive-course.php 與 single-course.php 控制列表與單篇頁面。
// archive-course.php 中可使用一般 Loop
if (have_posts()) {
while (have_posts()) {
the_post();
the_title('<h2>', '</h2>');
the_excerpt();
}
}
REST API 與區塊編輯器
show_in_rest 設為 true 後,CPT 才能完整支援區塊編輯器,也能透過 REST API 存取。若未來要做前後端分離或自訂區塊,這個設定很重要。
本章練習
- 建立
courseCPT。 - 新增三筆課程資料。
- 建立課程封存頁模板。
- 加入一個課程分類法,例如「難度」。