上一篇文章提到區塊分成「內容寫死的靜態區塊」和「內容即時查資料的動態區塊」。這一篇來解釋這條界線,因為它是整個第三部做自訂區塊時,你第一個要做的架構決定,選錯的話後面需要燒 Token 來挽救,而對從傳統主題過來的人,最快的理解捷徑是把它跟 ACF 放在一起看。
先講一個容易搞混的點:靜態和動態,指的不是「區塊會不會變」,而是「內容存在哪、什麼時候被組出來」。
靜態區塊,是把使用者輸入的內容,連同 HTML 結構,直接存進文章的 post_content。上一篇看到的那些 <!-- wp:paragraph --> 帶著 <p>這是一段內文。</p>,就是靜態區塊,內容(那段文字)和外殼(<p> 標籤)一起寫死在資料庫的字串裡。
它的運作是這樣:使用者在編輯器打字,區塊的 save 函式把「屬性 + HTML」序列化成一段字串,存進文章。前台顯示時 WordPress 不需要再做任何運算,直接把那段存好的 HTML 吐出來就好。
好處是快、前台零運算、對快取極友善,壞處是內容被「凍」在存檔那一刻:如果你之後改了區塊的 HTML 結構,舊文章裡那些已經存好的靜態區塊不會自動更新,還會跳出「此區塊發生錯誤」的 block validation 警告,核心的段落、標題、圖片,絕大多數都是靜態區塊。
動態區塊反過來。它不把內容 HTML 存進文章,只存一組屬性(設定),前台每次載入時才用 PHP 即時把 HTML 渲染出來。
負責組裝的是一支 render.php(在 block.json 裡用 render 指向它)。使用者在編輯器選的設定存進屬性,前台載入時 WordPress 呼叫 render.php,讀那些屬性、去資料庫撈最新資料、當場產生 HTML:
<?php
// render.php — 前台每次載入都會執行。
$posts = get_posts( array( 'numberposts' => $attributes['count'] ) );
foreach ( $posts as $post ) {
echo '<li>' . esc_html( $post->post_title ) . '</li>';
}
好處是內容永遠即時,像「最新五篇文章」這種區塊,你今天發新文,它明天自動更新,因為 HTML 是每次載入才組的,壞處是每次載入都要跑 PHP、查資料庫,成本比靜態高。凡是內容會隨資料庫變動的區塊,最新文章、購物車數量、會員資訊都必須做成動態區塊。
回想你用 ACF 的流程:開一個欄位讓客戶填內容,前台模板用 the_field() 把值撈出來、當場拼進 HTML,注意這個「填的內容存一邊、顯示時才撈出來組」的模式——這根本就是動態區塊的邏輯。ACF 的欄位值存在 wp_postmeta,動態區塊的屬性存在區塊標記或 meta,兩者都是「資料與呈現分離,顯示時才組合」。
所以如果你用 ACF 用得很熟,動態區塊對你來說不是新概念,只是換了個地方存屬性、換用 render.php 取代 single.php 裡那段 the_field() 迴圈。差別在於,動態區塊把「這塊資料 + 這段呈現邏輯」打包成一個可重複使用、可在任何頁面拖放的獨立單元,而 ACF 的呈現邏輯是綁死在特定模板檔裡的。
實作時怎麼選?看這張表:
| 判斷點 | 選靜態 Block | 選動態 Block |
|---|---|---|
| 內容來源 | 使用者手打、寫死 | 查資料庫、隨資料變動 |
| 前台成本 | 零運算,最快 | 每次載入跑 PHP |
| 內容即時性 | 存檔當下凍結 | 永遠最新 |
| 改結構後舊文章 | 可能跳 validation 錯誤 | 自動套用新結構 |
| 傳統主題類比 | 直接寫在模板的 HTML | ACF 開自訂欄位 |
| 典型例子 | 段落、標題、CTA 按鈕 | 最新文章、會員資訊、購物車 |
一個實用的判斷法則:內容會不會在「這篇文章存檔後」還自己變? 會,就動態;不會,就靜態。CTA 按鈕文字存檔後不會自己變,靜態就好;「最新三篇文章」存檔後還會隨你發新文而變,那非動態不可。
新手容易犯的錯,是什麼都做成動態區塊,覺得「動態比較強」。這是誤會。動態區塊每次載入都吃 PHP 和資料庫,濫用會拖垮前台效能。原則很簡單:能靜態就靜態,非得即時才動態。 靜態是預設值,動態是為了「內容必須跟資料庫同步」才付出的成本。
搞懂靜態與動態,你就掌握了自訂區塊最核心的架構選擇。明天我們換個層面,看 Block Theme 怎麼用 Global Styles 和 Style Variations,做到「一鍵切換整站配色字體」,這件事傳統主題要靠好幾套 CSS 才辦得到。
文章目錄:https://oberonlai.blog/category/2026-ithome/