メニュー

東京・小金井市のWEB制作会社の豆知識

MEMORANDUM

WordPress(ワードプレス)でカスタム投稿タイプにカスタムフィールド機能を追加

カスタムフィールド機能の追加は、プラグインでも可能ですが、今回は投稿済の記事から選択して設定する必要があったので、function.phpに追記して実装した方法をメモ。

functions.php

//カスタム投稿(contents)追加
function create_post_type_contents() {
	register_post_type( //カスタム投稿
		'contents',
		array(
			'labels' => array('name' => __('用語説明'), 'singular_name' => __('用語説明'), 'menu_name' => __('用語説明'), 'edit_item' => __('用語説明を編集')),
			'supports' => array('title', 'editor', 'thumbnail', 'revisions'),
			'public' => true,
			'has_archive' => true,
			'rewrite' => array('slug' => 'contents'),//URL
			'menu_position' => 6
		)
	);

}
add_action('init', 'create_post_type_contents');

//カスタムフィールド追加
function hook_func_for_metabox(){
	add_meta_box( 
		'metabox_div_id',//メタボックスのdivに指定されるID
		'関連用語', //タイトル
		'html_for_metabox_1_func', //表示用のHTMLを出力するphp関数(下で定義)
		'contents', //どのタイプの記事入力画面で表示するか
		'normal'
	);
}
//メタボックスの中身を実装する
function html_for_metabox_1_func($post){
	$keyname = "field_1";
	
	//記事タイトルを配列に格納	
	$args=array(
		'post_type' => 'contents',
		'posts_per_page' => -1,
		'post__not_in' => array($post->ID) //自身の記事を除外
 	);
	
	$sub_query = new WP_Query($args);
	
	//登録済みの値を取得
	$get_value = get_post_meta($post->ID, $keyname, true);

	if($sub_query->have_posts()){		
		while($sub_query->have_posts()){
			$sub_query->the_post();
			if(in_array(get_the_ID(), $get_value)){
				echo('<label><input type="checkbox" name="'.$keyname.'[]" value="'.get_the_ID().'" checked="checked">'.get_the_title().'<label>');
			}else{
				echo('<label><input type="checkbox" name="'.$keyname.'[]" value="'.get_the_ID().'">'.get_the_title().'<label>');
			}
		}
	}
	wp_reset_postdata();
	
	//nonceを作成し、hiddenフィールドとして書き込む
	wp_nonce_field('action-'.$keyname, 'nonce-'.$keyname);
}
add_action('admin_menu', 'hook_func_for_metabox');

//カスタムフィールドの入力欄の中のデータをデータベースへ保存する
function hook_func_for_save_customfield( $post_id ){
	$custom_fields = array('field_1');
 
	foreach( $custom_fields as $d ) {
		if(isset($_POST['nonce-'.$d])){
		if(wp_verify_nonce($_POST['nonce-'.$d], 'action-'.$d)){
			if(current_user_can('edit_post', $post_id)){
				///// カスタムフィールドの値を更新 ///
				if(get_post_meta($post_id, $d) == ""){
					//新しいデータならデータを作成
					add_post_meta($post_id, $d, $_POST[$d], true);
				}
				elseif($_POST[$d] != get_post_meta($post_id, $d, true)){
					//既存にあるデータで内容が異なるなら更新
					update_post_meta($post_id, $d, $_POST[$d]);
				}elseif($_POST[$d] == ""){
					//入力内容が空ならデータの削除
					delete_post_meta($post_id, $d, get_post_meta($post_id, $d, true));
				}
			}
		}
		} 
	}
	return $post_id;
}  
add_action('save_post', 'hook_func_for_save_customfield');

カスタムフィールドの入力チェック

入力チェックはjavascriptで行う。

function check_contents_field(){
	global $post;
	if (is_admin() && $post->post_type == 'contents'){
	echo <<<END
	<script language="javascript" type="text/javascript">
	jQuery(document).ready(function(){
		jQuery('#publish').click(function() {
			//バリデーションの実行
			var error = [];
			if(jQuery("input[name='field_1']").val() ==''){
				error[0]="値を入力してください\n";
			}
			if(error.length > 0){
				alert(error[0]);
				return false;
			}
		});
	});
	</script>
	END;
	}
}
add_action('admin_head-post-new.php', 'check_contents_field');
add_action('admin_head-post.php', 'check_contents_field');

single-contents.php(表示画面)

<h3>関連用語</h3>
<ul>
<?php
if(!empty($post->field_1)){
	foreach($post->field_1 as $key => $value){
		echo('<li><a href="'.get_the_permalink($value).'">'.get_the_title($value).'</a></li>');
	}
}
?>
</ul>

尚、カスタムフィールドの登録にプラグイン「ACF(Advanced Custom Fields)」を使用している場合は、競合(上書き)が発生する場合があるため保存方法に注意が必要。
フックに「save_post」ではなく「acf/save_post」を使用します。

functions.php

function hook_func_for_save_customfield_acf( $post_id ){
    // リビジョンは除外
    if (wp_is_post_revision($post_id)) return;

    // 投稿タイプを限定(必要に応じて変更)
    if ('post_b' !== get_post_type($post_id)) return;

    $custom_fields = array('field_1');

    foreach( $custom_fields as $d ) {
        if(isset($_POST['nonce-'.$d]) && wp_verify_nonce($_POST['nonce-'.$d], 'action-'.$d)) {
            if(current_user_can('edit_post', $post_id)) {
                $new_value = isset($_POST[$d]) ? $_POST[$d] : '';

                $old_value = get_post_meta($post_id, $d, true);

                if($old_value === '' && $new_value !== ''){
                    // 新しいデータなら作成
                    add_post_meta($post_id, $d, $new_value, true);
                } elseif($old_value !== '' && $new_value !== $old_value){
                    // 既存データで内容が異なる場合は更新
                    update_post_meta($post_id, $d, $new_value);
                } elseif($new_value === ''){
                    // 入力内容が空なら削除
                    delete_post_meta($post_id, $d, $old_value);
                }
            }
        }
    }

    return $post_id;
}

// acf/save_post にフック、優先度20でACF保存後に実行
add_action('acf/save_post', 'hook_func_for_save_customfield_acf', 20);
RANKING

人気記事

同一カテゴリーの記事