0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPress 7.0のiframeエディタで、クラシックメタボックスが引き起こす問題と移行【register_post_meta】

0
Posted at

自分のプラグインを7.0で動かしたら、メタボックスに仕込んでいたJavaScriptが、急に効かなくなりました。

エラーも出ていません。ただ、いつも掴んでいたはずのエディタの要素が、document.querySelector で取れない。null が返ってくる。半年前に書いて、ずっと動いていたコードです。何も変えていないのに、動かなくなった。

原因を追いかけて、ブロックエディタが7.0でiframeの中に入ったことに行き当たりました。ここから芋づる式に、add_meta_box で作ってきたメタボックスそのものが、7.0の新しい編集体験と噛み合わなくなっていることも分かりました。この2つは、根が同じで、直し方も同じです。移行したときの手順を書きます。

(※ 7.0まわりは開発中に仕様の変動がありました。最終的な挙動は、必ず公式のフィールドガイドと自分の環境で確認してください)

なぜ、掴めなくなったのか

7.0の前まで、ブロックエディタは、管理画面と同じページの中で動いていました。だから、メタボックスに置いたJavaScriptから、エディタの要素を document.querySelector で掴んで、値を読んだり書いたりできた。同じ文書の中にあったからです。

7.0では、エディタがiframeの中に入ります。iframeは、外側のページとは別の文書です。外から document.querySelector でエディタ内の要素を探しても、見つかりません。別の文書だから、掴めない。段階導入で、7.1(2026年8月)で完全に強制されます。

// ❌ 7.0のiframe化で動かなくなる:外側のdocumentからエディタ内を探す
const title = document.querySelector('.editor-post-title__input');
title.value = '...'; // iframe内なので、外側のdocumentからは掴めない

エディタの中を触りたいなら、DOMを直接掴むのではなく、エディタが用意しているデータのAPI(@wordpress/data など)を経由します。DOMの位置に依存したコードは、iframe化のたびに壊れる。位置ではなくデータで扱う、が7.0以降の前提でした。

クラシックメタボックスの、もう一つの問題

JSが掴めない件を追ううちに、add_meta_box 自体にも、別の問題があると分かりました。

7.0の目玉は、複数人が同じ投稿を同時に編集する仕組みです。ここに制約があります。クラシックメタボックスがある投稿タイプは、その同時編集が無効になる。Classicブロック(core/freeform)がある投稿も同様です。

つまり、add_meta_box を使い続けると、その投稿タイプだけ、7.0の新しい編集体験から外れます。動かなくなるわけではありませんが、新機能に乗れない旧道に取り残される。しかもiframe化で、メタボックス内のJSも見直しが要る。旧来のやり方が、二重に効かなくなっていく感じでした。

移行:register_post_meta に寄せる

対処は、メタボックスでやっていたことを、登録済みメタ+REST公開に移すことです。iframeの件も、メタボックスの件も、これで一度に片づきます。

まず、自分のプラグインの add_meta_box を全部洗い出します。ここが移行の起点です。

grep -rn "add_meta_box" ./

見つかったメタを、register_post_meta で登録し直します。肝は show_in_rest => true です。これがあると、ブロックエディタ側(REST経由)からメタを読み書きできるようになります。

add_action('init', function () {
    register_post_meta('post', 'myplugin_subtitle', [
        'show_in_rest'  => true,   // これでエディタ(REST)から扱える
        'single'        => true,
        'type'          => 'string',
        'auth_callback' => function () {
            return current_user_can('edit_posts');
        },
    ]);
});

auth_callback を省くと、権限チェックが緩くなります。誰がこのメタを書き換えられるかを、ここで明示しておきます。

入力UIは、エディタ側のパネルで出す

メタボックスのHTMLフォームの代わりは、エディタのサイドパネル(プラグインサイドバー/ドキュメント設定パネル)に置きます。ここはJavaScript側の実装になります。

// エディタのドキュメント設定パネルに、メタの入力欄を足す(概念コード)
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { useEntityProp } from '@wordpress/core-data';
import { TextControl } from '@wordpress/components';

const Panel = () => {
    const [meta, setMeta] = useEntityProp('postType', 'post', 'meta');
    return (
        <PluginDocumentSettingPanel title="Myplugin">
            <TextControl
                label="サブタイトル"
                value={ meta.myplugin_subtitle || '' }
                onChange={ (v) => setMeta({ ...meta, myplugin_subtitle: v }) }
            />
        </PluginDocumentSettingPanel>
    );
};
registerPlugin('myplugin-panel', { render: Panel });

DOMを直接掴んでいたころと違い、useEntityProp でメタを読み書きします。iframeの内か外かを気にしなくて済むのが、この形の利点です。エディタが管理しているデータに、正規の経路で触るからです。冒頭で null が返ってきた原因は、そもそもDOMを掴みにいっていたことでした。

保存側は、そのままでいい部分もある

register_post_metashow_in_rest を有効にしておくと、エディタからの保存はREST経由で処理されます。旧来の save_post$_POST を拾って update_post_meta していた処理は、エディタ経由の保存では通らなくなることがあります。

ただ、クラシックエディタや外部からの保存経路も残すなら、save_post 側を併存させる判断はありえます。自分は、エディタ経由をRESTに寄せつつ、nonceと権限を見たうえで save_post も残す形にしました。ここは、プラグインがどの経路から保存されうるかで変わります。

確認する順番

移行したら、この順で確かめます。

まず、メタがRESTに出ているか。/wp-json/wp/v2/posts/{id} を見て、meta に自分のキーがあるか。無ければ show_in_rest が原因です。

次に、エディタのパネルで値が読み書きできるか。入力して、保存して、リロードして残るか。

最後に、旧メタボックスのJavaScriptが、iframe前提のDOM操作を残していないか。document.querySelector でエディタ内を掴んでいる箇所がないか、grepで洗います。冒頭の自分のミスが、まさにこれでした。

早見でまとめ

  • 7.0でエディタがiframe化(7.1で完全強制)。外側のdocumentからエディタ内DOMは掴めない
  • クラシックメタボックス(add_meta_box)がある投稿タイプは、同時編集が無効になる
  • 対処は register_post_meta + show_in_rest => true。iframe対応とメタボックス問題を一度に解決
  • 入力UIはエディタのパネルへ。useEntityProp でメタを読み書き(DOM直接操作をやめる)
  • 保存経路は要確認。エディタ経由はREST。save_postを残すかはプラグイン次第
  • 確認は「RESTに出ているか → パネルで読み書き → 旧JSのDOM操作の残り」の順

7.0対応で、いちばん腰が重かったのが、この add_meta_box からの移行でした。長く使ってきた書き方なので。ただ、データをRESTに出す形に寄せておくと、iframe化にも同時編集にも乗れて、結果として身軽になりました。役に立ったらストックして、7.0/7.1対応のとき見返してください。


ふだんはraplsworks.comで、WordPressプラグイン開発やClaude Codeまわりのことを書いています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?