打開任何一個 WordPress 佈景主題資料夾,第一次看到一堆 index.php、single.php、functions.php、style.css 混在一起,多數人都會愣住,不知道哪個檔案在管什麼、哪些是必要、哪些只是慣例。其實主題檔案結構不是隨意擺放,而是 WordPress 有一套固定的辨識邏輯與命名規範在背後運作。摸清楚主題檔案結構,等於拿到改版、除錯、開發自訂主題的地圖。
這篇會把 WordPress 主題的目錄結構、必要檔案、範本檔命名規則,以及檔案彼此之間的載入邏輯一次講清楚,並區分傳統主題(Classic Theme)與區塊主題(Block Theme)兩種型態的差異,讓你看完就能自己拆解任何一套主題。
WordPress 主題放在哪個目錄,最少需要哪些檔案
所有主題都放在 wp-content/themes/ 底下,每一套主題各自佔一個子資料夾,資料夾名稱就是這套主題的識別字串(slug)。WordPress 啟動時會掃描這個目錄,把每個合格的子資料夾列進後台「外觀 — 佈景主題」清單。
一套主題能被 WordPress 認得、正常啟用,最少只需要兩個檔案,但傳統主題與區塊主題要求的那兩個檔案不同:
- 傳統主題:
style.css加上index.php - 區塊主題:
style.css加上templates/index.html
style.css 兩種主題都需要,因為主題的名稱、作者、版本號這些後台要顯示的資訊,全寫在這個檔案開頭的註解區塊裡。差別在主版型:傳統主題用根目錄的 index.php,區塊主題則要在 templates 資料夾裡放一個 index.html,少了它 WordPress 不會把這套東西當成區塊主題處理。
只放這兩個檔案的主題當然能跑,但畫面會非常陽春,因為 index.php 或 index.html 得獨力扛起整站所有頁面的呈現。實務上主題會再拆出數十個範本檔,各自負責不同類型的頁面。
style.css 的檔頭註解為什麼是必填,要寫哪些欄位
style.css 不只是樣式表,它開頭的註解區塊是 WordPress 辨識主題身分的唯一來源,少了它後台根本不會顯示這套主題。這個檔頭至少要有主題名稱(Theme Name),其餘欄位用來補充說明:
- Theme Name:主題顯示名稱,後台清單看到的就是它
- Author:作者名稱
- Version:版本號,建議用語意化版號(例如 1.0.0),改版時遞增
- Description:一句話描述這套主題的用途
- Text Domain:翻譯用的文字網域,做多語系時對應
load_theme_textdomain() - Template:只有子主題要填,值是父主題的資料夾名稱
style.css 必須放在主題根目錄,不能塞進 css 子資料夾,否則 WordPress 找不到檔頭。至於實際的視覺樣式,現代主題通常另外拆到 assets/css/ 底下管理,根目錄這支 style.css 主要負責檔頭與少量全域樣式。
index.php 與範本階層,WordPress 怎麼決定載入哪個檔案
index.php 是整套範本的最後防線:當 WordPress 找不到更精確的範本檔時,一律回頭用它來輸出頁面。這套「先找精確、找不到再退而求其次」的決策邏輯,就是範本階層(Template Hierarchy)。
訪客打開某個網址時,WordPress 會先判斷這是哪一種內容(單篇文章、頁面、分類彙整、搜尋結果等),再依固定順序去主題資料夾裡找對應的範本檔,找到第一個存在的就用它,沒找到就往下退一層,最終退到 index.php。
舉幾個常見的退讓鏈:
- 看一篇文章:
single-{post-type}.php→single.php→singular.php→index.php - 看一個頁面:
page-{slug}.php→page-{id}.php→page.php→singular.php→index.php - 看分類彙整:
category-{slug}.php→category-{id}.php→category.php→archive.php→index.php
最精確:自訂文章類型
一般單篇文章
文章與頁面共用後備
最後防線:全部退到這
理解這條鏈最大的好處,是除錯時知道該改哪個檔案。如果只想改文章頁的版面,新增 single.php 就好,不必動到 index.php 影響全站;想單獨替某個自訂文章類型做版型,就用 single-{post-type}.php 這種更精確的命名插進階層上層。
傳統主題的標準目錄結構長什麼樣
傳統主題把主要範本檔放在根目錄,再把樣式、圖片、JavaScript、輔助函式分門別類收進子資料夾。官方推薦的 Twenty 系列預設主題就是最好的範例,以 Twenty Seventeen 為例,它的結構大致是這樣:
twentyseventeen/
├── assets/
│ ├── css/
│ ├── images/
│ └── js/
├── inc/
├── template-parts/
│ ├── header/
│ ├── footer/
│ ├── navigation/
│ ├── page/
│ └── post/
├── 404.php
├── archive.php
├── comments.php
├── footer.php
├── front-page.php
├── functions.php
├── header.php
├── index.php
├── page.php
├── search.php
├── sidebar.php
├── single.php
├── rtl.css
├── screenshot.png
└── style.css
根目錄那一票 .php 是範本階層會直接點名的範本檔,命名固定、不能亂改,改了 WordPress 就認不得。子資料夾則是慣例性的整理方式,名稱有相當的彈性。
各範本檔的職責可以這樣對照:
| 檔案 | 負責的頁面 |
|---|---|
index.php |
萬用後備,所有內容的最終退讓目標 |
front-page.php |
網站首頁,存在時優先於其他首頁設定 |
home.php |
最新文章列表頁(部落格首頁) |
single.php |
單篇文章 |
page.php |
單一頁面 |
archive.php |
彙整頁(分類、標籤、作者、日期的通用版) |
category.php |
分類彙整,比 archive.php 更精確 |
search.php |
搜尋結果頁 |
404.php |
找不到內容時的錯誤頁 |
comments.php |
留言區範本,被允許留言的頁面引入 |
header、footer、sidebar 這些片段檔怎麼被組進頁面
header.php、footer.php、sidebar.php 屬於「範本片段」(Template Part),它們不單獨對應某個網址,而是被其他範本檔引入、變成頁面的一部分。這樣同一個頁首、頁尾只要寫一次,全站範本都能重複套用。
傳統主題用範本標籤(Template Tag)這類內建 PHP 函式把片段組裝進來。常見的引入函式有這幾個:
get_header():引入header.php,輸出頁首get_footer():引入footer.php,輸出頁尾get_sidebar():引入sidebar.php,輸出側邊欄get_search_form():輸出搜尋表單get_template_part():引入自訂的範本片段,例如放在template-parts/裡的零件
所以一支 single.php 通常開頭呼叫 get_header()、中間用迴圈跑文章內容、視需要 get_sidebar(),最後 get_footer() 收尾。把重複版面抽成片段檔,是傳統主題維持可維護性的核心做法。
範本檔命名規範,動態變數欄位怎麼對應內容
WordPress 靠檔名來判斷一個範本檔該套用到哪種內容,所以命名不是自由發揮,而是要符合固定格式。許多範本檔名支援帶入動態欄位,用大括號標示的部分會被換成實際的 slug、ID 或類型名稱:
| 命名格式 | 套用時機 | 範例 |
|---|---|---|
single-{post-type}.php |
特定自訂文章類型的單篇 | single-book.php 對應 book 類型 |
archive-{post-type}.php |
特定自訂文章類型的彙整 | archive-books.php |
page-{slug}.php |
指定 slug 的頁面 | page-about.php 對應 about 頁 |
category-{slug}.php |
指定分類的彙整 | category-news.php |
tag.php |
標籤彙整 | 全站標籤通用 |
taxonomy.php |
自訂分類法的詞彙頁 | 自訂 taxonomy 通用 |
author.php |
作者頁 | 載入作者彙整時使用 |
date.php |
依日期彙整 | 年、月、日的封存頁 |
命名規則本身有幾條底線要守住。範本檔名一律用小寫、單字之間用連字號,動態欄位要填真實存在的 slug 或類型名稱才會生效。rtl.css 是特例,當網站語言是由右到左書寫(例如阿拉伯語)時會自動載入。另外,主題資料夾名稱(也就是 slug)不要用純數字開頭命名,否則可能不會出現在後台的可用主題清單裡。
區塊主題的結構與傳統主題差在哪
區塊主題是 WordPress 5.9 之後推出的新型態,最大差異在於範本不再是混雜 PHP 的檔案,而是純 HTML 加上區塊標記(Block Markup),而且範本檔被集中收進固定命名的資料夾。一套典型的區塊主題結構像這樣:
my-block-theme/
├── parts/
│ ├── header.html
│ └── footer.html
├── patterns/
│ └── example.php
├── styles/
│ └── variation.json
├── templates/
│ ├── index.html (必要)
│ ├── 404.html
│ ├── archive.html
│ └── singular.html
├── functions.php
├── screenshot.png
├── style.css (必要)
└── theme.json
幾個資料夾在區塊主題裡有強制規定的用途,不能隨意更名:
templates:放頂層範本,index.html是必要檔,少了它 WordPress 不認為這是區塊主題parts:放範本片段,例如header.html、footer.html,對應傳統主題的header.phppatterns:放可重複使用的區塊樣式,放進來的檔案 WordPress 會自動註冊styles:放樣式變體,每個變體是一個 JSON 檔,讓使用者一鍵切換配色與字體
區塊主題最關鍵的新檔案是 theme.json,它用一個 JSON 檔集中設定全站的色票、字級、間距、版面寬度等全域樣式,並直接和後台編輯器介面整合。傳統主題要靠 PHP 與 CSS 才能做到的全域設定,區塊主題改由 theme.json 統一管理。
組裝片段的方式也跟著改變。傳統主題用 get_header() 這類函式,區塊主題則在範本裡寫區塊標記,例如以 <!-- wp:template-part {"slug":"header"} /--> 引入名為 header 的片段,這裡的 slug 就是 parts 資料夾裡那個 HTML 檔的檔名。
兩種型態的對照可以這樣看:
| 面向 | 傳統主題 | 區塊主題 |
|---|---|---|
| 必要檔 | style.css + index.php |
style.css + templates/index.html |
| 範本檔格式 | PHP(含 HTML 與範本標籤) | HTML(含區塊標記) |
| 範本存放位置 | 根目錄 | templates 資料夾 |
| 片段存放位置 | 慣例放 template-parts,無強制 |
強制放 parts 資料夾 |
| 全域設定 | 寫在 PHP 與 CSS | 集中在 theme.json |
| 引入片段 | get_header() 等函式 |
wp:template-part 區塊標記 |
值得注意的是,兩種主題的範本階層判斷邏輯其實相同,差別只在副檔名與存放位置:傳統主題找 single.php,區塊主題就找 templates/single.html,退讓順序一模一樣。
functions.php 與其他選擇性檔案各自管什麼
functions.php 不負責輸出任何畫面,它的角色是在主題載入後自動被 WordPress 執行的 PHP 檔,用來掛載功能。註冊選單、啟用主題支援的功能(縮圖、自訂選單、區塊樣式)、載入 CSS 與 JS、定義小工具區,這些都寫在這裡。傳統主題與區塊主題都可以有 functions.php。
除了範本檔與 functions.php,主題裡常見的選擇性檔案還有幾類,缺了不影響運作但實務上幾乎都會放:
screenshot.png:後台清單顯示的主題縮圖,尺寸不能超過 1200 × 900 像素,.png與.jpg都可接受README.txt:給使用者看的說明文件,要上架官方主題目錄時是必要檔languages/:放多語系翻譯檔(.pot與各語言的.mo),資料夾名稱可改但要同步更新load_theme_textdomain()inc/(或includes、src):放拆分出來的 PHP 類別與輔助函式,避免functions.php過度膨脹assets/(或resources、public):放 CSS、圖片、JavaScript 等靜態資源
另外一批是開發工具相關的設定檔,例如 .gitignore、.editorconfig、CHANGELOG.md、package.json、LICENSE.md,它們和 WordPress 本身的運作無關,純粹服務版本控制與建置流程,要不要放看開發習慣。順帶一提,所有上架官方主題目錄的主題都必須採用 GPL v2 以上授權,這會寫在 LICENSE.md 裡。
想改主題又不想動到原檔,子主題的結構怎麼建
子主題(Child Theme)是繼承既有主題、只覆寫想改部分的做法,好處是父主題更新時你的修改不會被蓋掉。它的結構非常精簡,最少只要一個資料夾加上一個 style.css:
twentytwentyfour-child/
├── style.css
└── functions.php (選擇性)
關鍵在子主題的 style.css 檔頭多了一個 Template 欄位,值要填父主題的資料夾名稱,WordPress 看到這欄就知道該繼承哪一套主題。子主題沒有的範本檔會自動沿用父主題的版本,有同名檔案則優先用子主題的,所以想改哪個範本,就把對應檔案複製進子主題再修改。
子主題的 functions.php 不會覆蓋父主題的,而是兩支都會被載入,這點和範本檔的覆寫邏輯相反。需要載入父主題樣式或追加功能時,就把程式碼寫在子主題的 functions.php 裡。
從一堆檔案到一張地圖,接下來怎麼動手
主題檔案結構的核心,就是「WordPress 用檔名與資料夾位置來決定載入什麼」這一條規則。根目錄(或 templates 資料夾)的範本檔靠固定命名對應頁面類型,範本階層決定退讓順序,style.css 檔頭定義主題身分,functions.php 掛載功能,其餘子資料夾則是維持整潔的慣例。
下一步最實際的練習,是打開站上正在用的主題資料夾,對照本文的範本檔對照表,逐一確認每個檔案在管哪個頁面。要改版時,先判斷目標頁面落在範本階層的哪一層,再決定是新增精確範本檔、還是建一個子主題來覆寫,就不會再對著一堆檔案無從下手。