WordPress 2.5+ 引入 Shortcode API,允許開發者以宏標籤形式在文章/頁面/側邊欄插入動態內容。類似 BBCode 但更強大:支援 PHP 邏輯、參數解析、巢狀標籤、內容過濾。
| 型態 | 語法範例 | 說明 |
|---|---|---|
| 自閉合 | [myshortcode] | 無內容、無參數 |
| 帶參數自閉合 | [myshortcode title="範例" num="5"] | 參數以屬性形式傳遞 |
| 封閉標籤 | [myshortcode]內容[/myshortcode] | 包裹內容,可為 HTML/文字 |
| 封閉+參數 | [myshortcode class="box"]內容[/myshortcode] | 參數與內容並存 |
| 巢狀標籤 | [outer][inner]...[/inner][/outer] | 需處理器支援遞歸解析 |
add_shortcode(string $tag, callable $callback);
$tag:短代碼名稱 (小寫、無空格、勿與核心衝突)$callback:處理函數,接收 ($atts, $content = null)functions.php
function info_box_shortcode($atts, $content = null) {
// 1. 解析並預設參數
$atts = shortcode_atts([
'title' => '提示',
'type' => 'info', // info, warning, danger, success
'class' => '',
], $atts, 'info_box');
// 2. 過濾內容 (允許短代碼巢狀)
$content = do_shortcode($content);
// 3. 產出 HTML
$typeClass = 'alert-' . sanitize_html_class($atts['type']);
$customClass = sanitize_html_class($atts['class']);
return '<div class="alert ' . $typeClass . ' ' . $customClass . '">'
. '<h4>' . esc_html($atts['title']) . '</h4>'
. '<div>' . $content . '</div>'
. '</div>';
}
add_shortcode('info_box', 'info_box_shortcode');
文章中使用
[info_box title="系統公告" type="warning"] 本站將於今晚 22:00 進行維護,預計 30 分鐘。 [/info_box] [info_box title="新功能" type="success" class="mb-3"] 歡迎體驗全新的深色模式! [/info_box]
$defaults = ['title' => '預設標題', 'limit' => 10]; $atts = shortcode_atts($defaults, $atts, 'my_tag'); // 結果:合併用戶參數,未提供者用預設,濾除非預期參數 // 第三參數 'my_tag' 可讓其他插件透過 filter 'shortcode_atts_my_tag' 修改預設值
extract($atts); // $title, $limit 直接可用 // 注意:變數名衝突風險,現代開發建議直接用 $atts['title']
$content = do_shortcode($content); // 遞歸處理內容中的其他 shortcode
remove_shortcode('tag'); // 移除單一
remove_all_shortcodes(); // 移除所有 (慎用)
if (shortcode_exists('gallery')) { /* ... */ }
$pattern = get_shortcode_regex(); // 取得匹配所有 shortcode 的正則
preg_match_all('/' . $pattern . '/s', $content, $matches);
// $matches[2] = tag 名稱,$matches[3] = 參數字串,$matches[5] = 內容
function posts_list_shortcode($atts) {
$atts = shortcode_atts([
'category' => '',
'tag' => '',
'number' => 5,
'orderby' => 'date',
'order' => 'DESC',
'template' => 'list', // list, grid, card
], $atts, 'posts_list');
$queryArgs = [
'posts_per_page' => (int)$atts['number'],
'orderby' => sanitize_key($atts['orderby']),
'order' => sanitize_key($atts['order']),
'post_status' => 'publish',
];
if ($atts['category']) $queryArgs['category_name'] = sanitize_title($atts['category']);
if ($atts['tag']) $queryArgs['tag'] = sanitize_title($atts['tag']);
$posts = new WP_Query($queryArgs);
ob_start();
if ($posts->have_posts()) {
// 載入模板部件
while ($posts->have_posts()) {
$posts->the_post();
get_template_part('template-parts/post', $atts['template']);
}
} else {
echo '<p>暫無文章</p>';
}
wp_reset_postdata();
return ob_get_clean();
}
add_shortcode('posts_list', 'posts_list_shortcode');
使用:[posts_list category="news" number="10" template="card"]
現代 WordPress 開發建議同時提供區塊與 Shortcode 雙重介面:
可用 @wordpress/create-block 建立區塊,內部渲染邏輯複用 Shortcode 回調函數。
| 原則 | 做法 |
|---|---|
| 輸出轉義 | esc_html(), esc_attr(), esc_url(), wp_kses_post() |
| 參數清理 | sanitize_text_field(), sanitize_html_class(), absint() |
| 權限檢查 | 若涉及敏感操作,current_user_can() 驗證 |
| Nonce 驗證 | 表單提交類 shortcode 需 wp_verify_nonce() |
| 效能 | 避免 shortcode 內直接重複查詢 DB,善用 Transients 快取 |
| 命名空間 | 前綴如 myplugin_ 避免衝突 |
// 1. 查看當前註冊的所有 shortcode
global $shortcode_tags;
var_dump(array_keys($shortcode_tags));
// 2. 臨時禁用特定 shortcode (functions.php)
add_action('init', function() {
remove_shortcode('problematic_tag');
});
// 3. 記錄 shortcode 執行 (開發環境)
add_filter('do_shortcode_tag', function($output, $tag, $atts) {
error_log("Shortcode [$tag] atts: " . print_r($atts, true));
return $output;
}, 10, 3);
Shortcode 是 WordPress 內容擴展的利器:add_shortcode() 註冊、shortcode_atts() 參數預設、do_shortcode() 巢狀支援、輸出必須轉義。現代開發建議區塊優先、Shortcode 互補,並嚴守安全原則。掌握核心 API 後,即可開發出強大、安全、易用的內容編輯功能。