WordPressカスタマイズ事例

Custom Field Suiteを使ったカスタムフィールドを持つページの「プレビュー」を表示する

固定ページや投稿、カスタム投稿タイプなどにカスタムフィールドを持たせることがよくあります。
入力の手間が省け、htmlの知識がない人でも簡単に高機能なWebレイアウトを作ることができとても便利です。
ところが、カスタムフィールド管理のプラグインでCustom Field Suiteを使うと、「プレビュー」(「更新」せずに表示を確認できる機能)ができない、という問題があります。

そこで今回は、Custom Field Suiteを使ったカスタムフィールドを持つページの「プレビュー」を表示する方法のご紹介。

まずプラグインを作り、有効にします。
(作り方の基礎が知りたければWordPressのプラグインを作成する(初級)を参考にしてください。)

<?php
/*
Plugin Name: Custom field suite preview bug fix
Author: kaiza
Plugin URI: 
Description: Custom field suite preview bug fix
Version: 0.1.0
Author URI: 
*/
$cfs_fix = new Custom_Field_Suite_Preview();
class Custom_Field_Suite_Preview {
function __construct(){
add_action('plugins_loaded', array($this, 'plugins_loaded'));
}
public function plugins_loaded(){
add_action('cfs_init', array($this, 'cfs_init'), 0);
add_action('wp_insert_post', array($this, 'wp_insert_post'));
add_filter('get_post_metadata', array($this, 'get_post_metadata'), 10, 4 );
add_shortcode('cfs_get', function($p){
extract(shortcode_atts(array(
'key' => false,
'id' => 0,
'format' => array(),
), $p));
return self::get($key, $id, $format);
});
}
public function get($key, $id = 0, $format = array()){
global $cfs;
if (intval($this->get_preview_id($id))) {
return $cfs->get($key, $this->get_preview_id($id), $format);
} elseif ($id = $this->get_preview_id(get_the_ID())) {
return $cfs->get($key, $id, $format);
} else {
return $cfs->get($key, get_the_ID(), $format);
}
}
public function cfs_init(){
if (isset($_POST['wp-preview']) && $_POST['wp-preview'] === 'dopreview') {
global $cfs;
remove_action('cfs_init', array($cfs->form, 'init'));
}
}
public function get_preview_id( $post_id ){
global $post;
$preview_id = 0;
if (isset($post->ID) && intval($post->ID) === intval($post_id) && is_preview()
&& $preview = wp_get_post_autosave($post->ID)) {
$preview_id = $preview->ID;
}
return $preview_id;
}
public function get_post_metadata( $return, $post_id, $meta_key, $single ) {
if ($preview_id = $this->get_preview_id($post_id)) {
if ($post_id !== $preview_id) {
$return = get_post_meta($preview_id, $meta_key, $single);
}
}
return $return;
}
public function wp_insert_post($post_ID){
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (defined('DOING_AJAX') && DOING_AJAX) {
return;
}
if (wp_is_post_revision($post_ID)) {
global $wpdb;
global $cfs;
$wpdb->query($wpdb->prepare(
"DELETE FROM $wpdb->postmeta WHERE post_id = %d",
$post_ID
));
$cfs->form->session = new cfs_session();
$session = $cfs->form->session->get();
$field_groups = array();
if (isset($session['field_groups'])) {
$field_groups = $session['field_groups'];
}
foreach ($field_groups as $key => $val) {
$field_groups[$key] = (int) $val;
}
$options = array(
'format' => 'input',
'field_groups' => $field_groups
);
$cfs->save($_POST['cfs']['input'], array('ID' => $post_ID), $options);
$post_metas = array('meta');
foreach ( $post_metas as $post_meta ) {
foreach ( $_POST[$post_meta] as $meta_id => $meta_arr ) {
add_metadata('post', $post_ID, $meta_arr['key'], $meta_arr['value']);
}
}
}
}
}

これで、「プレビュー」が押されたときに、Custom Field Suiteで作ったカスタムフィールドの値を自動セーブします。
 
今度は表示側(page.phpなど)です。
自動セーブされた値を取得するために、Custom Field Suiteの関数は使わず、WordPress標準のget_post_meta関数を使ってカスタムフィールドを読み込むようにします。

<? php 
//画像の読み込み
$image1 = get_post_meta($post->ID, 'image1', true);
$image1 = content_url().'/uploads/'.get_post_meta($image1, '_wp_attached_file', true);
//テキストの読み込み
$text1 = get_post_meta($post->ID, 'text1', true);
//繰り返しフィールドの読み込み
$repeat1_fields = get_post_meta($post->ID, 'repeat1', false);
$count_total = count($repeat1_fields );
$count_total = $count_total/2; //同じ値が2つ登録されるので1つだけ取り出すための調整式
$repeat_fields = array();
for($i = 0; $i < $count_total; $i++){
$repeat_fields[$i]['repeat1']=$repeat1_fields[$i];
}
?>
テキスト表示
<?php echo $text1; ?>
画像表示
<img src="<?php echo $image1; ?>" >
繰り返しフィールドの表示
foreach ($repeat_fields as $repeat_field) {
echo $repeat_field['repeat1'].'<br>';
}

これでプレビュー表示されます。
 
 
※ ただし、これをしても、2回に1回しか変更した内容が反映されたページは表示されません。
2回に1回は変更前の“今公開されているページ”がプレビューとして現れます。
なぜそうなるかまでは突き止められませんでした。
ちなみに私たちが普段使っているカスタムフィールド管理用プラグイン Advanced Custom Fieldsでも同じ現象が起きます。。

あしからず。


関連するWordPressカスタマイズ事例