Custom post type UIでカスタム投稿を準備し、カスタムフィールドテンプレートを使用せず、独自にfunctions.phpでカスタムフィールドを作成し、投稿機能を作成した。

記事を投稿し、公開した後、更新作業してプレビュー表示するとエラーが表示するというバグが発生。

通常のカスタムフィールドテンプレートをしなかった理由として、セレクトボックスの値を動的に変える必要があったため、独自で作成する必要があった。

現象が起きる要点として、以下のことが分かった。

  • 一度公開した記事は、プレビューボタンをクリックすると、仮投稿IDが作成され、save_postが実行されている。
  • カスタムフィールドの値は、保存されないと反映、データの取得ができない。

その為、通常の公開更新、プレビューの分岐で機能の実行を分ける必要性があると判断。

ちなみに、カスタムフィールドテンプレートなどのプラグインは、予めこのような対策はされているようで、プレビューで値が反映しないというバグは見られなかった。

// functions.php内でsave_postをフックで使用している場合、プレビュー機能時と通常更新時の分岐をする必要がある
// プレビュー機能時は$_POST['wp-preview']に「dopreview」という文字列が代入されている
if(empty($_POST['wp-preview'])) {// プレビューの場合は実行しない
	update_post_meta($post_id, $value, $data);
}

以下はカスタムフィールド系のプラグインを使用してもプレビューに入力データが反映しない場合の設定例

// preview用に保存された下書き情報(post)のIDを取得する
function get_preview_id($postId)
{
    global $post;
    $previewId = 0;
 
    if (($post->ID == $postId) && $_GET['preview'] == true &&  ($postId == url_to_postid($_SERVER['REQUEST_URI']))) {
        // プレビュー表示の際に、自動保存されたpostの下書き情報を取得する
        $preview = wp_get_post_autosave($postId);
        if ($preview != false) { $previewId = $preview->ID; }
    }
 
    return $previewId;
}

function get_preview_postmeta($metaValue, $postId, $metaKey, $single)
{
    // プレビュー表示のときにmeta情報(custom fileds情報)を、
    // プレビュー用のmeta情報に置き換える
    if ($previewId = get_preview_id($postId)) {
        if ($postId != $previewId) {
            $metaValue = get_post_meta($previewId, $metaKey, $single);
        }
    }
 
    return $metaValue;
}
add_filter('get_post_metadata', 'get_preview_postmeta', 10, 4);
 
// 下書き情報を作成するときに、対応するcustom filed情報も作成する
// プレビューの際には、この時作ったcustom filed情報を読み出す
// (読み出しているのが、get_preview_postmetaの部分)
// $_POST['post_ID'] には公開済みID $post_IDにプレビュー用仮ID

function save_preview_postmeta($post_ID){

	global $wpdb;

	if ( wp_is_post_revision( $post_ID ) ) {
		// カスタムフィールドのキー名を配列で準備する。
		$job_meta_ary = array('office_name','sub_office_name','job_catchcopy','job_category','work_about','employment','job_area','work_time',
	    		'requirements','wages','holiday_other','welfare','documents','note',);

		foreach ($job_meta_ary as $value) {
			//add_metadata('post', $post_ID, $value, $_POST[$value]);
			update_metadata('post', $post_ID, $value, $_POST[$value]);
	    }

	    do_action( 'save_preview_postmeta', $post_ID );
	}
}
add_action('wp_insert_post', 'save_preview_postmeta');