公開済みの記事を編集してプレビューするとカスタムフィールドの値が古いままなのを解決する
※公式対応までのつなぎ
functions.phpに下記追記
/**
* $dataをjsonで出力
*/
function echo_json($data)
{
header("Content-Type: application/json; charset=utf-8");
echo json_encode($data);
}
/**
* テンプレートのadmin.jsを読み込む
*/
function add_admin_style()
{
$path_js = get_template_directory_uri().'/scripts/admin.js';
wp_enqueue_script('admin_script', $path_js);
}
add_action('admin_enqueue_scripts', 'add_admin_style');
/**
* ajaxで送信されたカスタムフィールドの値をdbへ保存
*/
function save_acf_by_ajax()
{
if(empty($_POST['post_id'])){
echo_json(['success' => false,'preview_id' => 0]);
wp_die();
exit;
}
$post_id = $_POST['post_id'];
$post_status = get_post_status($post_id);
if($post_status !== "publish"){
echo_json(['success' => false,'preview_id' => 0]);
wp_die();
exit;
}
$preview_id = 0;
global $wpdb;
$row = $wpdb->get_row("SELECT p.ID FROM $wpdb->posts AS p WHERE p.post_type = '_cf_preview_id' AND p.post_parent = ${post_id}");
if(empty($row)) {
$post = array(
'post_name' => '_cf_preview_id',
'post_title' => '_cf_preview_id',
'post_status' => 'private',
'post_type' => '_cf_preview_id',
'post_author' => 1,
'ping_status' => 'closed',
'post_parent' => $post_id,
'comment_status' => 'closed',
);
$preview_id = wp_insert_post($post);
}else{
$preview_id = $row->ID;
}
unset($_POST['action']);
unset($_POST['post_id']);
unset($_POST['preview_id']);
if(!empty($preview_id)) {
foreach ($_POST as $key => $value) {
update_field($key, $value, $preview_id);
}
}
$_POST['post_id'] = $post_id;
$_POST['preview_id'] = $preview_id;
$_POST['success'] = !empty($preview_id);
echo_json($_POST);
wp_die();
}
add_action( 'wp_ajax_save_acf_by_ajax_action', 'save_acf_by_ajax' );
/**
* プレビュー時カスタムフィールドの値用のpostidを返す
*/
function get_cf_post_id($post_id = '')
{
if(empty($post_id)){
$post_id = get_the_ID();
}
$cf_post_id = $post_id;
if(is_preview()){
$post_status = get_post_status($post_id);
if($post_status === 'publish'){
global $wpdb;
$row = $wpdb->get_row("SELECT p.ID FROM $wpdb->posts AS p WHERE p.post_type = '_cf_preview_id' AND p.post_parent = ${post_id}");
if (!empty($row)) {
$cf_post_id = $row->ID;
}
}
}
return $cf_post_id;
}
wp-content/themes/テーマ/assets/js/admin.jsに下記追記
class CFSaveManager {
qsall(selector,elm){
if(!elm)elm = document;
return elm.querySelectorAll(selector);
}
qs(selector,elm){
if(!elm)elm = document;
return elm.querySelector(selector);
}
constructor(){
}
/* 初期化 */
init(){
this.initAutoSave();
}
/* プレビューボタンにイベント設定 */
initAutoSave(){
const button = this.qs('.block-editor-post-preview__button-toggle');
if(!button){
setTimeout(() => {
this.initAutoSave();
},200);
return;
}
button.addEventListener('click',() => {
this.autoSave();
});
}
/* ajaxでカスタムフィールドの値をapiへ送信・保存 */
autoSave(){
const elm = this.qs('[name="post_ID"]');
const form = this.qs('form.metabox-location-normal');
const formData = new FormData(form);
let sendFormData = new FormData();
for (let item of formData) {
if(/^acf\[.+\]$/.test(item[0])){
var matches = item[0].match(/acf\[(.+)\]/);
if(matches && 1 < matches.length){
sendFormData.append(matches[1],item[1]);
}
}else{
sendFormData.append(item[0],item[1]);
}
}
sendFormData.append('action','save_acf_by_ajax_action');
sendFormData.append('post_id',elm.value);
const options = {
method : "POST",
headers : {
'Accept': 'application/json'
},
body : sendFormData
};
fetch(window.ajaxurl,options)
.then((response)=>{
if (!response.ok) {
throw new Error();
}
return response.json();
})
.then((json)=>{
console.log(json);
})
.catch(console.error);
}
}
window.addEventListener('DOMContentLoaded',(e) => {
const cfsm = new CFSaveManager();
cfsm.init();
});
wpテンプレでカスタムフィールドの値を出力する部分
$post_id = get_the_ID();
$cf_preview_id = $post_id;
if(is_preview()){
$post_status = get_post_status($post_id);
if($post_status === 'publish'){
global $wpdb;
$row = $wpdb->get_row("SELECT p.ID FROM $wpdb->posts AS p WHERE p.post_type = '_cf_preview_id' AND p.post_parent = ${post_id}");
if (!empty($row)) {
$cf_preview_id = $row->ID;
}
}
}
$value = get_field( "test_text1" ,$cf_preview_id );
echo "cf_preview_id:$cf_preview_id<br>";
echo "<h2>test_text1:".esc_html($value)."</h2>";