テンプレートで出力される内容を $post->post_content に入れる
ショップというカスタム投稿タイプを作って、このショップの投稿では店名や住所などをカスタムフィールドで入力して、それら情報のみをページに出力。このとき本文はそもそも入力しないというケース。
このままでは $post->post_content が空っぽなので、たとえばカスタムフィールドで入力した住所などで検索したときにヒットしない。
カスタムフィールドを検索対象にするという手もあるけど、データベースに負荷かかるし、 $post->post_content が空っぽなのはやはりちょっとイヤなので、記事を保存するときに出力されるページのコンテンツ部分を $post->post_content にぶっこむことにする。
こういう場合はアクションフック save_post を使えばいいので、最初は次のようにした。
function save_shop( $post_id, $post, $update ) {
if ( $post_obj->post_type == 'shop' ) {
ob_start();
setup_postdata( $post );
get_template_part( 'templates/content', 'shop' );
$shop_content = ob_get_contents();
wp_reset_postdata();
ob_end_clean();
$args = array(
'ID' => $post_id,
'post_content' => $shop_content,
);
remove_action( 'save_post', 'save_shop' );
wp_update_post( $args );
add_action( 'save_post', 'save_shop', 10, 3 );
}
}
add_action( 'save_post', 'save_shop', 10, 3 );
get_template_part( ‘templates/content’, ‘shop’ ) で出力される内容を ob_get_content() で取得して $shop_content に代入。その後、wp_update_post() で投稿データを更新する。
ちなみにこのとき、remove_action( ‘save_post’, ‘save_shop’ ) としているのは wp_update_post() でフックした関数が呼び出されてしまい無限ループに陥いるのを避けるため。
参考) プラグイン API/アクションフック一覧/save post
うまく行ったかに思えたけど、一括操作で更新するとうまく行かない…
これで投稿を更新してみたら、うまく行った。ところが投稿一覧で投稿を選択して、一括操作の編集でまとめて更新してみるとうまく行かない。
テンプレートの内容は取得できているようだけど、肝心のカスタムフィールドの値が取得できていない。。どうも setup_postdata( $post ) がうまく働いていないよう。うーんなんでだろうと調べてみたら、公式リファレンスには
$post グローバル変数へのリファレンスを指定しなければなりません。そうしないと the_title() などの関数が正しく動作しません。
出典: 関数リファレンス/setup postdata
要は setup_postdata( $post ) の $post はグローバル変数の $post にしなければいけないということのようだ。
上記のコードの $post はフックした関数 save_shop が受け取った引数なわけだ。
ってことで、 以下のように save_shop( $post_id, $post_obj, $update ) と修正して、この関数内でグローバル変数 $post を呼び出して、$post = $post_obj と割り当ててやればうまく行った。
function save_shop( $post_id, $post_obj, $update ) {
if ( $post_obj->post_type == 'shop' ) {
global $post;
$post = $post_obj;
ob_start();
setup_postdata( $post );
get_template_part( 'templates/content', 'shop' );
$shop_content = ob_get_contents();
wp_reset_postdata();
ob_end_clean();
$args = array(
'ID' => $post_id,
'post_content' => $shop_content,
);
remove_action( 'save_post', 'save_shop' );
wp_update_post( $args );
add_action( 'save_post', 'save_shop', 10, 3 );
}
}
add_action( 'save_post', 'save_shop', 10, 3 );
setup_postdata( $post ) の $post はグローバル変数、ってのは頭のなかにはあったはずだけど、つい忘れていたということで以上まとめてみました。