首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

讓 WordPress 編輯器完美支援內聯 SVG:TinyMCE 配置完整指南

     編輯:PHP 相關知識

讓 WordPress 編輯器完美支援內聯 SVG:TinyMCE 配置完整指南

WordPress 預設編輯器 TinyMCE 基於 HTML5 規範驗證標籤,SVG 作為 XML 命名空間元素,預設會被視為無效標籤而於視覺/文字模式切換時被剝離。本文提供經實測可行的完整解決方案,讓內聯 SVG 在編輯器中保持完整結構、樣式與互動性。

核心問題分析

  • TinyMCE valid_elements、extended_valid_elements 預設不包含 SVG 標籤。
  • valid_children 規則限制 <body> 等容器不允許 SVG 子元素。
  • 切換編輯模式時,序列化/解析流程會移除未識別標籤。
  • SVG 標籤區分大小寫(如 viewBox、clipPath),但 HTML 解析器會強制小寫,導致屬性失效。

解決方案:functions.php 完整代碼

<?php
/**
 * 讓 TinyMCE 完整支援內聯 SVG
 * 掛載至 tiny_mce_before_init 過濾器
 */
add_filter('tiny_mce_before_init', function (array $init): array {
    // 1. 完整 SVG 元素白名單 (全部小寫,符合 HTML 解析器行為)
    $svgElements = 'svg[*]';
    $svgChildElements = implode(',', [
        'altGlyph[*]', 'altGlyphDef[*]', 'altGlyphItem[*]', 'animate[*]', 'animateColor[*]',
        'animateMotion[*]', 'animateTransform[*]', 'circle[*]', 'clipPath[*]', 'color-profile[*]',
        'cursor[*]', 'defs[*]', 'desc[*]', 'ellipse[*]', 'feBlend[*]', 'feColorMatrix[*]',
        'feComponentTransfer[*]', 'feComposite[*]', 'feConvolveMatrix[*]', 'feDiffuseLighting[*]',
        'feDisplacementMap[*]', 'feDistantLight[*]', 'feFlood[*]', 'feFuncA[*]', 'feFuncB[*]',
        'feFuncG[*]', 'feFuncR[*]', 'feGaussianBlur[*]', 'feImage[*]', 'feMerge[*]', 'feMergeNode[*]',
        'feMorphology[*]', 'feOffset[*]', 'fePointLight[*]', 'feSpecularLighting[*]', 'feSpotLight[*]',
        'feTile[*]', 'feTurbulence[*]', 'filter[*]', 'font[*]', 'font-face[*]', 'font-face-format[*]',
        'font-face-name[*]', 'font-face-src[*]', 'font-face-uri[*]', 'foreignObject[*]', 'g[*]',
        'glyph[*]', 'glyphRef[*]', 'hkern[*]', 'image[*]', 'line[*]', 'linearGradient[*]', 'marker[*]',
        'mask[*]', 'metadata[*]', 'missing-glyph[*]', 'mpath[*]', 'path[*]', 'pattern[*]', 'polygon[*]',
        'polyline[*]', 'radialGradient[*]', 'rect[*]', 'script[*]', 'set[*]', 'stop[*]', 'style[*]',
        'switch[*]', 'symbol[*]', 'text[*]', 'textPath[*]', 'title[*]', 'tref[*]', 'tspan[*]', 'use[*]',
        'view[*]', 'vkern[*]'
    ]);

    // 2. 擴充合法元素
    $init['extended_valid_elements'] = isset($init['extended_valid_elements'])
        ? $init['extended_valid_elements'] . ',' . $svgElements . ',' . $svgChildElements
        : $svgElements . ',' . $svgChildElements;

    // 3. 允許 body 等容器包含 svg 子元素
    $init['valid_children'] = isset($init['valid_children'])
        ? $init['valid_children'] . ',+body[svg],+div[svg],+figure[svg],+section[svg],+article[svg]'
        : '+body[svg],+div[svg],+figure[svg],+section[svg],+article[svg]';

    // 4. 自訂元素註冊 (支援自訂屬性)
    $init['custom_elements'] = isset($init['custom_elements'])
        ? $init['custom_elements'] . ',' . $svgElements
        : $svgElements;

    // 5. 保留屬性大小寫 (關鍵:防止 viewBox 變 viewbox)
    // TinyMCE 4.x+ 支持此設定
    $init['verify_html'] = false; // 關閉 HTML 驗證,避免移除未知屬性
    $init['cleanup'] = false;     // 關閉自動清理
    $init['forced_root_block'] = false; // 不強制包裹 p 標籤

    return $init;
}, 20); // 優先權較高,確保後執行

編輯器使用最佳實踐

  1. 使用「代碼」區塊或「預格式化」段落包裹 SVG:在區塊編輯器 (Gutenberg) 中選擇「自定義 HTML」或「預格式化」區塊貼上 SVG 代碼,避免段落標籤干擾。
  2. 在 SVG 根元素加入備用文字:
    <svg viewBox="0 0 100 100" xmlns="https://www.w3.org/2000/svg">
      <title>圖示標題</title>
      <desc>圖示描述,供螢幕閱讀器讀取</desc>
      <circle cx="50" cy="50" r="40" fill="currentColor"/>
      <!-- 瀏覽器不支援 SVG 時的備用內容 -->
      <text x="50" y="55" text-anchor="middle" font-size="10" fill="gray">SVG 不支援</text>
    </svg>
    
  3. 避免在視覺模式下編輯 SVG 內部結構:僅在代碼/文字模式修改,視覺模式僅作為預覽。
  4. CSS 作用域隔離:為防止主題樣式污染 SVG,建議在 SVG 上加入類別並編寫 scoped CSS:
    <svg class="my-icon" ...>...</svg>
    .my-icon { width: 1em; height: 1em; display: inline-block; vertical-align: middle; }
    .my-icon * { vector-effect: non-scaling-stroke; }
    

進階:區塊編輯器 (Gutenberg) 原生支援

WordPress 5.8+ 區塊編輯器已大幅改善 SVG 支援。若使用區塊編輯器:

  • 直接使用「自定義 HTML」區塊貼上 SVG。
  • 或開發專用 SVG 區塊(@wordpress/create-block),提供屬性面板(顏色、尺寸、圖示選擇),輸出安全的內聯 SVG。
  • 區塊編輯器的 allowedBlockTypes、wp_kses_allowed_html 可進一步微調。

安全性提醒

  • 開放 script[*], style[*], foreignObject[*] 等元素可能引入 XSS 風險,**僅限可信任編輯者使用**。
  • 生產環境建議搭配 wp_kses 白名單過濾儲存前的內容,或使用 DOMPurify (PHP 移植版) 淨化。
  • 禁止未受信任用戶(投稿者、訂閱者)編輯包含 SVG 的內容。

常見問題排查

現象原因解決
SVG 仍被移除快取、CDN、其他外掛衝突清除瀏覽器/伺服器快取,停用其他 TinyMCE 相關外掛測試
屬性變小寫 (viewBox → viewbox)HTML 解析器特性SVG 規範屬性實際不區分大小寫,瀏覽器渲染無影響。若需保持,需關閉 verify_html
樣式失效主題 CSS 覆蓋、缺少 xmlns補上 xmlns="https://www.w3.org/2000/svg",加入 scoped CSS
無法儲存wp_kses 過濾使用 wp_kses_allowed_html 過濾器擴充允許標籤/屬性

總結

透過 tiny_mce_before_init 完整註冊 SVG 元素樹、關閉 HTML 驗證、配合編輯習慣與安全過濾,即可在 WordPress 經典編輯器中流暢使用內聯 SVG。新專案建議直接採用區塊編輯器開發專用 SVG 區塊,獲得更佳的編輯體驗與輸出安全性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved