ACFの柔軟コンテンツで構築された投稿群をブロックエディターに置換する

ブロックエディター前には、クラシックエディタの大体としてACFの柔軟コンテンツを利用し、ブロックエディターのようにカスタムフィールドを利用して本文を作成するような手法がありました。今も利用できますが、ブロックエディターに置き換えられるなら、今後ブロックエディターの機能を十分に使えメリットが大きいです。

例えば1000以上の記事が柔軟コンテンツで作られているとして、それをなるべく自動的にブロックエディターに移行する方法をメモします。

1. 柔軟コンテンツの内容を本文にデータとして保存し直す

function.php側で記述するsave_postのタイミングで動かす関数

<?php
function insert_custom_field_value_on_save( $post_id ) {
	// WP-CLIでない場合、自動保存中でない場合、編集権限がある場合、リビジョンでない場合は処理を停止.
	if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}
		if ( wp_is_post_revision( $post_id ) ) {
			return;
		}
		//投稿タイプ hoge でない場合は処理を停止
		if ( 'hoge' !== get_post_type( $post_id ) ) {
			return;
		}
	}
	// カスタムフィールドの値の取得.

	ob_start();
	
?>
ここに柔軟コンテンツの出力部分をコピー
<?php

$custom_field_value = ob_get_contents(); // 記録結果を変数に代入
	ob_end_clean(); // 記録終了

	// 本文が空の場合のみ、本文に挿入.
	if ( ! empty( $custom_field_value ) ) {
		$post_content = get_post_field( 'post_content', $post_id );
		if ( $post_content == null ) {
			$post_content = $custom_field_value;
			global $wpdb;

			$wpdb->update( $wpdb->posts, array( 'post_content' => $post_content ), array( 'ID' => $post_id ) );
		}
	}
}
add_action( 'save_post', 'insert_custom_field_value_on_save' );

上記をWP CLIから動かす。下記はただ更新するためのwp cliのサンプル。日付などは適当に。この方法では更新日が固定の値に変わってしまうので、投稿ID別にsave_postだけ実行するカスタムコマンドを作ってもよい。

for id in $(wp post list --post_type=news --field=ID); do
  wp post update $id --post_modified='2024-05-08 10:00:00'
done

2. クラシックブロックとして登録されるコンテンツをブロックに変換する

上記を実行すると、クラシックブロックとして、保存されるため、それをブロックにコンバートする

  • 利用プラグイン
  • 利用コマンド
    • すべての投稿で実行する場合
      • wp convert-to-blocks start
      • このコマンド実行時に、表示される最初のURLをブラウザで開けば、後は順番にブラウザが記事を開き、それぞれを保存していく。手動でできる部分を自動化している状態で、作業が終わるまでブラウザを開いておく必要がある。
    • 投稿タイプhogeについて実行する場合
      • wp convert-to-blocks start –post_type=hoge
    • 作業を中断する場合
      • wp convert-to-blocks stop