ブロックエディタの見出しブロックでh1,h2,h3を使えないようにする

ブロックエディタを使っていて、見出しはh4からh6までだけを使って欲しいという技。
逆に言うとh1,h2,h3を使うのを禁止する技。WordPress5.9および6.0で有効。

以下の合わせ技で実現した。

  • 見出しブロックでh1,h2,h3を選択できないようにする
  • 保存時にh1,h2,h3があったらh4に書き換える
  • Wordからコピペしてきたときにh1,h2,h3をh4と同じように表示する

theme.jsonでなんとかならんかみたいな意見も見かけたので将来的には是非そうなっていただきたい。

見出しブロックでh1,h2,h3を選択できないようにする

管理画面にCSSを追加して隠す。力業。

css/admin-style.css

[aria-label="Heading 1"], [aria-label="Heading 2"], [aria-label="Heading 3"] {
    display: none;
}
[aria-label="見出し1"], [aria-label="見出し2"], [aria-label="見出し3"] {
    display: none;
}
/* https://wordpress.stackexchange.com/questions/383423/is-there-any-simple-way-to-remove-gutenberg-editor-h1-h5-h6-and-change-the-label */

参考にしたページによれば5.8以前は以下のCSSを遣えばいいらしいが試してはいない。

.block-library-heading-level-toolbar .components-toolbar-group {
    button:nth-child(1), button:nth-child(2), button:nth-child(3) {
        display: none;
    }
}

functions.php

add_action('admin_enqueue_scripts', function ($hook_suffix) {
  $uri = get_template_directory_uri() . "/css/admin-style.css";
  $path = get_template_directory() . "/css/admin-style.css";

  wp_enqueue_style("smart-style", $uri, array(), filemtime($path));
});

コピペされた時を想定して保存時にh1,h2,h3があったらh4に書き換える

ブロックエディタ上で防いでもWordからのコピペには無力。なので書き換える処理を入れる。

functions.php

    function restrict_headings($post_id) {
      global $post;
      if (!wp_is_post_revision($post_id)) {
        remove_action('save_post', 'restrict_headings');
    
        $post->post_content = preg_replace('/<!-- wp:heading( {"level":(1|2|3)}|) -->/', '<!-- wp:heading {"level":4} -->', $post->post_content);
        $post->post_content = preg_replace('/<h(1|2|3)>(.+)<\/h(1|2|3)>/', '<h4>${2}</h4>', $post->post_content);
        wp_update_post($post);
    
        add_action('save_post', 'restrict_headings');
      }
    }
    add_action('save_post', 'restrict_headings');

wp:headingはh2がデフォらしく、h2だとlevelが付かないのだけど何かの拍子で付くようになるかもしれないので置き換え対象に含めておく。むしろなんでh2をデフォルトを設定したのか。小一時間。

levelとhタグが合ってないと壊れたブロックとみなされるのでHTMLタグのh1,h2,h3もh4に変換している。

Wordからコピペしてきたときにh1,h2,h3をh4と同じように表示する

コピペ直後にh1,h2,h3が大きく表示されるが保存されると小さくなるのはユーザーが混乱する挙動なので、コピペした時点でh4と同じスタイルにしておく。

css/editor-style.css

/* コピペでh1,h2,h3が追加されたときに違和感ないように */
h1.wp-block-heading, h2.wp-block-heading, h3.wp-block-heading {
    font-size: 16px;
}

editor-style.cssはエディタ内に適用される。admin-style.cssは管理画面全体に適用される。

見出しブロックの設定でh1,h2,h3を選択できなくするスタイルをadmin-style.cssの方に入れてるのは、ブロックの設定をいじるUIはエディタ領域じゃなくて管理画面全体の方に属しているから。

functions.php

add_editor_style('css/editor-style.css');