Gutenberg、「新規追加」に難あり

説明

昨日公開した「Gutenberg、初見です」で自作プラグインの「複製」機能が正しく動作していないことについて軽く触れた。該当するプラグインを修正するにしても原因がはっきりしないと手の打ちようがない。そんなわけで、不具合の原因を調べてみた。

'default_content'フィルター

「複製」機能の実装は、管理画面向けのget_default_post_to_edit関数(/wp-admin/includes/post.php)が実行する'default_content'フィルターを利用している。get_default_post_to_edit関数は、名前の通り新規の投稿記事を編集する際のデフォルトの投稿データを用意しその内容を返すものだ。この関数の中では、いくつかのフィルターにより、デフォルトの投稿データが変更可能になっている。

  • 'default_content'フィルター
    デフォルトの投稿本文向け
  • 'default_title'フィルター
    デフォルトの投稿タイトル向け
  • 'default_excerpt'フィルター
    デフォルトの投稿抜粋向け

不具合の原因を絞り込むため、'default_content'フィルターが実行されているかを確認。投稿の「新規追加」は/wp-admin/post-new.phpファイルが実体なので、そのファイル中のget_default_post_to_edit関数の呼び出し直後に取得した$postの内容をダンプしてみた。

$post = get_default_post_to_edit( $post_type, true );

ダンプした内容には'default_content'フィルターで変更した内容が反映されており、フィルター自身が実行されていることが確認できた。

あらためてget_default_post_to_edit関数の処理内容を確認してみると、空の投稿データを登録してから各フィルターで投稿データを変更するようになっている。新しいエディターは編集開始時にREST APIによって編集対象の投稿データを取得していることを思い出し、新しいエディターはフィルターで変更をする前の空の投稿データが表示されているのではと仮説を立てる。そこで仮説を検証するため、get_default_post_to_edit関数で返り値を返す直前で強制的に投稿データを更新し(以下の赤字部分)、新しいエディターの表示が変化するか確認した。

	$post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post );

	$post->post_title = 'Hello';
	$post->post_content = 'World';
	wp_update_post( $post );

	return $post;

この状態で「新規追加」したところ、タイトルは空のままだが、本文には'World'が反映されることがわかった。

タイトルは空のままだが、本文には'World'が反映された

とりあえずチケット発行

タイトルが反映されないのは謎のままだが、不具合なのは確かだと思われる。そんなわけでTracに「Default title and content are not reflected in new editing.」を投稿。この不具合の対応を見てからプラグインを修正しようと思う。

Gutenbergをめぐる旅は次回へ続く。


最終更新 : 2018年08月07日 15:37

お勧め

get_comment_id_fields(2014年10月6日 更新)

string get_comment_id_fields( [ int $id = 0 ] )
コメント投稿フォームの隠しフィールドを取得する。

has_header_image(2018年5月27日 更新)

bool has_header_image( )
現在のテーマがヘッダー画像を持っているか調べる。

wp_generator(2018年5月27日 更新)

void wp_generator( )
XHTMLのgeneratorタグを表示する。

get_userdata(2018年5月27日 更新)

mixed get_userdata( int $user_id )
ユーザIDを指定し、マッチするユーザ情報を取得する。

get_the_content(2014年3月3日 更新)

string get_the_content( [ string $more_link_text = null [ , bool $strip_teaser = false ] ] )
現在の投稿情報のコンテンツを取得する。