この記事は最後に更新してから1年以上経過しています。

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をめぐる旅は次回へ続く。

【追記】11/25 WordPress 5.0 Beta1がリリースされ、こちらの不具合は解決した模様。すばら!


最終更新 : 2018年10月25日 13:00

お勧め

delete_option(2019年4月24日 更新)

bool delete_option( string $option )
サイトオプションを削除する。

flush_rewrite_rules(2015年9月24日 更新)

void flush_rewrite_rules( [ bool $hard = true ] )
リライトルールを更新する。

wp_nonce_tick(2014年5月20日 更新)

int wp_nonce_tick()
nonce用の時間依存値を取得する。

get_privacy_policy_url(2018年5月27日 更新)

string get_privacy_policy_url()
プライバシーポリシーページのURLを取得する。

delete_metadata(2016年2月23日 更新)

bool delete_metadata( string $meta_type, int $object_id, string $meta_key [ , mixed $meta_value = '' [ , bool $delete_all = false ] ] )
メタ情報の値を削除する。