本篇文章更新時間:2026/03/03
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知或向一介資男的 LINE 社群反應。
如果本站內容對你有幫助,歡迎贊助支持 。
本系列文參考自 WordPress.org 官方外掛開發文件 - Shortcodes 的繁體中文版本,並加入作者實務開發經驗補充。
WordPress 短碼開發是外掛開發者必須掌握的重要技能之一。Shortcodes(短碼)是 WordPress 自 2.5 版本開始引入的巨集機制,讓使用者能夠在文章或頁面內容中透過簡單的標記語法來執行動態功能。由於 WordPress 基於安全考量禁止在內容中直接執行 PHP 程式碼,短碼便成為了在內容區域中嵌入動態互動功能的標準解決方案。透過短碼,開發者可以將複雜的 PHP 邏輯封裝成簡潔的標記,讓不熟悉程式碼的使用者也能輕鬆使用進階功能。
內容目錄
什麼是 Shortcodes 短碼
Shortcodes 是一種以方括號包裹的特殊標記語法,例如 錯誤: 找不到符合條件的聯絡表單。 或 。當 WordPress 在文章內容中遇到短碼標記時,會自動將其替換為對應的 PHP 函式所產生的 HTML 輸出。這個機制類似於程式設計中的巨集(Macro)概念:開發者定義一段可重複使用的程式碼,使用者只需要輸入簡短的標記就能觸發這段程式碼的執行。
短碼的運作原理其實相當直觀。WordPress 在輸出文章內容之前,會使用正規表達式掃描內容中所有已註冊的短碼標記,然後呼叫對應的回呼函式來產生替換內容。這個過程發生在 the_content 過濾器中,透過 do_shortcode() 函式來執行。
短碼有三種基本形式:
- 自閉合短碼(Self-closing):
[shortcode]— 不包含內容,獨立運作 - 帶屬性短碼(With attributes):
[shortcode attr="value"]— 接受參數來自訂行為 - 包圍式短碼(Enclosing):
[shortcode]內容[/shortcode]— 包裹並處理中間的內容
建立基本短碼 - add_shortcode()
add_shortcode() 是註冊短碼的核心函式,它接受兩個參數:短碼名稱(tag)和回呼函式(callback)。當 WordPress 在內容中偵測到對應的短碼標記時,就會執行指定的回呼函式,並將函式的回傳值插入到內容中取代原本的短碼標記。
/**
* 註冊一個基本短碼
*
* 使用方式:在文章中輸入 [wporg]
* 輸出結果:一段歡迎訊息的 HTML
*/
function wporg_shortcode_callback( $atts, $content, $tag ) {
return '<p class="wporg-greeting">歡迎來到 WordPress.org!</p>';
}
add_shortcode( 'wporg', 'wporg_shortcode_callback' );
回呼函式會接收三個參數:
$atts(array):使用者在短碼中指定的屬性,以關聯陣列的形式傳入$content(string):包圍式短碼中被包裹的內容,自閉合短碼時為null$tag(string):短碼的名稱標記,當多個短碼共用同一個回呼函式時特別有用
短碼的註冊時機也需要注意。建議在 init 動作鉤子中註冊短碼,確保 WordPress 核心已完成初始化:
function wporg_register_shortcodes() {
add_shortcode( 'wporg', 'wporg_shortcode_callback' );
add_shortcode( 'wporg_box', 'wporg_box_shortcode_callback' );
}
add_action( 'init', 'wporg_register_shortcodes' );
以下是一個稍微實用的範例,建立一個顯示目前年份的短碼,常用於版權宣告等需要自動更新年份的場景:
/**
* 顯示目前年份的短碼
*
* 使用方式:Copyright © [current_year] My Company
* 輸出結果:Copyright © 2026 My Company
*/
function wporg_current_year_shortcode() {
return date( 'Y' );
}
add_shortcode( 'current_year', 'wporg_current_year_shortcode' );
短碼屬性 - shortcode_atts()
短碼的真正威力在於它能接受使用者傳入的屬性參數,讓同一個短碼根據不同的參數產生不同的輸出。shortcode_atts() 函式負責將使用者傳入的屬性與開發者定義的預設值進行合併,確保每個屬性都有值可用,同時過濾掉未定義的屬性。
/**
* 帶屬性的短碼範例
*
* 使用方式:[wporg_box title="注意事項" color="red" size="large"]
*/
function wporg_box_shortcode_callback( $atts ) {
// 定義預設屬性值並與使用者傳入的屬性合併
$atts = shortcode_atts(
array(
'title' => '提示', // 預設標題
'color' => 'blue', // 預設顏色
'size' => 'medium', // 預設尺寸
),
$atts,
'wporg_box' // 短碼名稱,用於 shortcode_atts_{shortcode} 過濾器
);
// 清理屬性值
$title = esc_html( $atts['title'] );
$color = sanitize_html_class( $atts['color'] );
$size = sanitize_html_class( $atts['size'] );
return sprintf(
'<div class="wporg-box wporg-box--%1$s wporg-box--%2$s"><h3>%3$s</h3></div>',
$color,
$size,
$title
);
}
add_shortcode( 'wporg_box', 'wporg_box_shortcode_callback' );
shortcode_atts() 的第三個參數是短碼名稱,傳入這個參數後,WordPress 會自動觸發 shortcode_atts_{shortcode} 過濾器。這讓其他外掛或佈景主題有機會修改你的短碼預設值,提升了短碼的可擴展性:
// 其他開發者可以透過過濾器修改 wporg_box 短碼的預設屬性
add_filter( 'shortcode_atts_wporg_box', function( $out, $pairs, $atts ) {
// 強制覆蓋某個屬性值
$out['color'] = 'green';
return $out;
}, 10, 3 );
需要特別注意的是,短碼屬性名稱會被 WordPress 自動轉換為小寫。因此在定義屬性時,請一律使用小寫名稱,避免使用駝峰式命名(camelCase)或大寫字母,以免造成屬性值遺失的問題。
包圍式短碼(Enclosing Shortcodes)
包圍式短碼可以包裹一段內容,透過回呼函式的 $content 參數來接收和處理這段內容。這種形式特別適合用來為內容加上特定的樣式容器、執行文字轉換,或是建立可重複使用的內容模板。
/**
* 包圍式短碼範例 - 建立重點提示區塊
*
* 使用方式:
* [wporg_highlight type="warning"]
* 這段內容會被包裹在醒目的提示區塊中。
* 支援 HTML 標記和其他短碼。
* [/wporg_highlight]
*/
function wporg_highlight_shortcode( $atts, $content = null ) {
$atts = shortcode_atts(
array(
'type' => 'info', // info, warning, error, success
),
$atts,
'wporg_highlight'
);
// 如果沒有內容,回傳空字串
if ( is_null( $content ) ) {
return '';
}
$type = sanitize_html_class( $atts['type'] );
// 處理內容中的段落和嵌套短碼
$content = do_shortcode( $content );
return sprintf(
'<div class="wporg-highlight wporg-highlight--%s">%s</div>',
esc_attr( $type ),
wp_kses_post( $content )
);
}
add_shortcode( 'wporg_highlight', 'wporg_highlight_shortcode' );
包圍式短碼有幾個重要的注意事項:
- 嵌套短碼的處理:如果你希望包圍式短碼中的其他短碼也能正常執行,需要在回呼函式中對
$content呼叫do_shortcode()。WordPress 不會自動處理嵌套在包圍式短碼內部的短碼。 - 不支援同名巢狀:WordPress 的短碼解析器不支援同名短碼的巢狀使用。例如
[wporg_highlight][wporg_highlight]內容[/wporg_highlight][/wporg_highlight]會產生非預期的結果。如果需要巢狀功能,請使用不同的短碼名稱。 - 內容中的 HTML:包圍式短碼中的
$content可能包含使用者輸入的 HTML。務必使用wp_kses_post()等函式來過濾內容,避免 XSS 攻擊。
以下是一個更完整的範例,建立一個支援標題和多種樣式的內容區塊:
/**
* 進階包圍式短碼 - 內容卡片
*
* 使用方式:
* [wporg_card title="快速入門" icon="rocket"]
* 按照以下步驟開始使用外掛...
* [/wporg_card]
*/
function wporg_card_shortcode( $atts, $content = null ) {
$atts = shortcode_atts(
array(
'title' => '',
'icon' => '',
),
$atts,
'wporg_card'
);
if ( is_null( $content ) ) {
return '';
}
$output = '<div class="wporg-card">';
if ( ! empty( $atts['title'] ) ) {
$output .= sprintf(
'<div class="wporg-card__header"><h3>%s%s</h3></div>',
! empty( $atts['icon'] ) ? '<span class="dashicons dashicons-' . esc_attr( $atts['icon'] ) . '"></span> ' : '',
esc_html( $atts['title'] )
);
}
$output .= '<div class="wporg-card__body">';
$output .= wp_kses_post( do_shortcode( $content ) );
$output .= '</div></div>';
return $output;
}
add_shortcode( 'wporg_card', 'wporg_card_shortcode' );
WordPress 內建短碼
WordPress 核心內建了數個實用的短碼,開發者在建立自訂短碼之前,應該先了解這些內建功能,避免重複造輪子:
:為圖片加上標題說明,常搭配媒體庫使用,會產生<figure>和<figcaption>標記:顯示圖片庫,可指定文章 ID、欄數、圖片大小等屬性,例如:嵌入音訊播放器,支援 mp3、ogg、wav 等格式,例如:嵌入影片播放器,支援 mp4、webm、ogv 等格式,可設定寬高和自動播放:建立音訊或影片的播放清單,支援多個媒體檔案的連續播放:嵌入外部內容(如 YouTube 影片、Twitter 貼文),利用 oEmbed 協定自動取得嵌入碼
你可以使用 shortcode_exists() 來檢查某個短碼是否已經被註冊,以及使用 has_shortcode() 來檢查特定內容中是否包含某個短碼。這兩個函式在條件載入資源(CSS/JS)時特別實用:
// 只在文章內容包含特定短碼時才載入對應的 CSS 和 JavaScript
function wporg_enqueue_shortcode_assets() {
global $post;
if ( is_singular() && has_shortcode( $post->post_content, 'wporg_box' ) ) {
wp_enqueue_style( 'wporg-box-style', plugins_url( 'css/box.css', __FILE__ ) );
wp_enqueue_script( 'wporg-box-script', plugins_url( 'js/box.js', __FILE__ ), array(), '1.0', true );
}
}
add_action( 'wp_enqueue_scripts', 'wporg_enqueue_shortcode_assets' );
短碼開發最佳實踐
在開發短碼時,遵循以下最佳實踐能確保你的短碼穩定、安全且易於維護:
1. 永遠回傳(return),不要輸出(echo)
這是短碼開發中最重要的規則。短碼的回呼函式必須回傳(return)一個字串,而不是直接輸出(echo)內容。如果使用 echo,輸出的內容會在錯誤的位置顯示,通常會出現在頁面最頂端而非短碼所在的位置,因為短碼的處理發生在內容渲染之前。
// 錯誤示範 - 使用 echo 會導致內容位置錯亂
function wporg_bad_shortcode() {
echo '<p>這段文字會出現在錯誤的位置!</p>';
}
// 正確做法 - 使用 return 回傳字串
function wporg_good_shortcode() {
return '<p>這段文字會正確顯示在短碼所在位置。</p>';
}
// 如果必須使用會產生輸出的函式,請用輸出緩衝區
function wporg_buffer_shortcode() {
ob_start();
// 某些無法避免 echo 的情況,例如呼叫第三方函式庫
some_function_that_echoes();
return ob_get_clean();
}
2. 為短碼名稱加上前綴
為避免與其他外掛或佈景主題的短碼名稱衝突,請為你的短碼加上獨特的前綴。建議使用外掛名稱或品牌名稱的縮寫作為前綴:
// 不好的做法 - 容易與其他外掛衝突
add_shortcode( 'box', 'my_box_shortcode' );
add_shortcode( 'button', 'my_button_shortcode' );
// 好的做法 - 加上外掛前綴
add_shortcode( 'myplugin_box', 'myplugin_box_shortcode' );
add_shortcode( 'myplugin_button', 'myplugin_button_shortcode' );
3. 資料清理與輸出跳脫
短碼的屬性值來自使用者輸入,必須視為不可信任的資料。在使用屬性值之前,務必進行適當的清理(Sanitize);在輸出時,務必進行跳脫(Escape)。關於 WordPress 資料安全處理的完整說明,請參考外掛開發安全性指南。
function wporg_secure_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'url' => '',
'title' => '',
'class' => '',
),
$atts,
'wporg_link'
);
// 針對不同類型的資料使用對應的清理函式
$url = esc_url( $atts['url'] );
$title = esc_html( $atts['title'] );
$class = sanitize_html_class( $atts['class'] );
if ( empty( $url ) || empty( $title ) ) {
return '';
}
// 輸出時使用跳脫函式
return sprintf(
'<a href="%s" class="%s">%s</a>',
esc_url( $url ),
esc_attr( $class ),
esc_html( $title )
);
}
add_shortcode( 'wporg_link', 'wporg_secure_shortcode' );
4. 移除短碼的時機
如果你需要移除已註冊的短碼(例如在某些條件下停用功能),可以使用 remove_shortcode()。移除短碼的動作必須在短碼被註冊之後執行:
// 移除指定的短碼
remove_shortcode( 'wporg_box' );
// 移除所有已註冊的短碼
remove_all_shortcodes();
5. 短碼中載入外部資源
避免在短碼的回呼函式中直接呼叫 wp_enqueue_style() 或 wp_enqueue_script(),因為短碼執行的時機可能在 wp_head 之後,導致資源無法正確載入到 <head> 中。正確的做法是在 wp_enqueue_scripts 鉤子中使用 has_shortcode() 來判斷是否需要載入資源(如前面「WordPress 內建短碼」章節中的範例所示),或是將 JavaScript 放到頁尾載入。
作者實務經驗分享:
在現代 WordPress 開發中(5.0 版本之後),Gutenberg 區塊編輯器(Block Editor)已經成為建立自訂內容功能的主流方式。區塊提供了即時視覺預覽、更直觀的編輯體驗,以及更豐富的使用者介面控制。然而,短碼在許多場景下仍然有其不可取代的價值:
1. 簡單功能快速實作:如果你只需要一個插入動態內容的功能(例如顯示目前年份、使用者名稱等),寫一個短碼只需要幾行 PHP 程式碼,而建立一個完整的 Gutenberg 區塊則需要 PHP 加上 React/JavaScript、webpack 編譯等一整套工具鏈。對於小型功能來說,短碼的開發成本遠低於區塊。
2. 向下相容性:許多現有的 WordPress 網站仍然使用傳統編輯器,或是內容中已經大量使用了短碼。在這些情境下,短碼是最穩定的選擇。
3. 非內容區域的使用:短碼可以透過
do_shortcode()在小工具(Widget)、模板檔案等非文章內容的區域中使用,這是區塊目前較難做到的。我的建議是:對於新開發的外掛,如果功能複雜且需要豐富的使用者介面互動,優先考慮使用 Gutenberg 區塊;如果功能簡單或需要最大的相容性,短碼仍然是最務實的選擇。兩者並不互斥,許多成熟的外掛會同時提供區塊和短碼兩種使用方式,讓使用者自行選擇。
本文是「WordPress 外掛開發完整指南」系列的第 7 篇。
上一篇:[WordPress] Settings API 教學 - 外掛設定頁面開發完整指南
下一篇:[WordPress] Metadata 與 Custom Meta Box 開發教學
