⚰️

クラシックエディタからブロックエディタに移行した古いコンテンツをクラシックブロックとして共存させる

2024/09/02に公開

前提

  • ブロックエディタ登場以前にローンチしたWordPressサイト(クラシックエディタープラグイン有効化状態)をハイブリッドテーマにする
  • 過去コンテンツをブロック変換するなどのマイグレーションは実施しない
  • h2などの基本的なHTMLタグの標準の外観がハイブリッドテーマ以降変更される(!)

つまり、過去コンテンツのスタイル・今後のブロックエディタのスタイルを共存させる必要がある

対応方法を考えた

WordPressの各ブロックには.wp-block-headingのようなクラスが付与されることが多い。
クラシックブロックのクラス名で旧CSSをカプセル化すれば良いのでは?と考えた。

クラシックブロックの特徴

以下のような動作を確認した。

  • クラシックブロックプラグインを無効化しブロックエディタ化されると、過去入力内容は全て「クラシックブロック」になる(として扱われる)
  • クラシックブロックには<!-- wp:... -->というようなシリアライズされたコメント文が無いため、blockNameがnullになる
  • the_content()から出力されるクラシックブロックは、ラッパー要素やクラス名が付与されずに内容がそのまま出力される
    • スコープが不明のため、このままでは旧CSSをカプセル化することができない

そのため、以下のような処理を作成する必要がある

  1. 「固有のCSSクラス名が付いたラッパー要素」を追加する処理
  2. その「ラッパー要素を追加する」判定処理

(※.wp-block-freeformというCSSクラスが付与されている?という情報も見かけたが、自分の場合はそういったものは出力されなかった)

考えた判定条件

完成のイメージ

説明のためにかなり簡単なHTMLタグを配置している(本当にこうなら別に書き分ける意味はない...)が、
クラシックブロックに実際に入っているものは、

  • MindBEMベースでコーディングされたカードUI
  • 旧Bootstrapライクなグリッドシステム

など、独自のHTML構造・独自のCSSクラス名が付与されたコンポーネントのHTMLも多数ある

<div class="editor-styles-wrapper">
    <h2 class="wp-block-heading">見出しブロック</h2>
    <p>段落ブロック</p>
    <div class="classic-block">
        <h2>見出し</h2>
        <p>文章</p>
    </div>
    <p>段落ブロック</p>
</div>
.wp-block-heading:is(h2) {} /* ハイブリッドテーマ化以降のCSS */
.classic-block h2 {} /* クラシックエディタ時代のCSS */

コード

functions.php

次のようなコードを書いて完成

function render_classic_block_wrapper( $block_content, $block ) {
    // クラシックブロックを判定するための条件
    $is_classic_block = (
        ( is_null( $block['blockName'] ) || $block['blockName'] === 'core/freeform' ) &&
        !empty( $block_content ) &&
        preg_match( '/<[^>]+>/', $block_content ) &&
        strpos( $block_content, '<!-- wp:' ) === false
    );

    if ( $is_classic_block ) {
        $block_content = '<div class="classic-block">' . $block_content . '</div>';
    }

    return $block_content;
}
add_filter( 'render_block', 'render_classic_block_wrapper', 10, 2 );

参考

Discussion