ミギムキ

[WordPress] 二つのカスタム投稿をタクソノミーは使わずに紐付けたい

あるカスタム投稿に別のカスタム投稿を関連付けて管理したい、というケースがあります。
例えば、「製品情報」のカスタム投稿に「オプション」のカスタム投稿を紐付けるといった場合です。

よくある方法としては、二つのカスタム投稿に共通のタクソノミー、タームを設定することで関連付けを行うことがあります。
しかしこの方法では、投稿が増えるたびにタームの追加も行う必要があるため、少し手間がかかります。

タクソノミーを使わずに、カスタムフィールドを使って二つのカスタム投稿を関連付けることで、下図のように編集画面から直感的に設定できるようになります。

画像に alt 属性が指定されていません。ファイル名: custom-post-to-merge-001.png

上図は「オプション」というカスタム投稿が紐付けられたカスタム投稿「製品情報」の編集画面です。
カスタムフィールドとして「オプション」の投稿が一覧表示されており、関連付けたいものにチェックをつけることができます。

サンプルコード

functions.php

function add_meta_box_product() { add_meta_box( 'meta_box_product', '選択可能なオプション', 'meta_box_product_callback', array('product'), 'normal' ); } add_action('admin_menu', 'add_meta_box_product'); function meta_box_product_callback() { global $post; $options = get_post_meta($post->ID, 'mb_options', true); $args = array( 'post_type' => 'option', 'posts_per_page' => '-1' ); $the_query = new WP_Query($args); if($the_query->have_posts()) { while($the_query->have_posts()) { $the_query->the_post(); $title = get_the_title(); $id = get_the_ID(); $checked = ''; if(!empty($options) && in_array($id, $options)) { $checked = 'checked="checked"'; } echo '<label style="margin: 0px 2em 0px 0px;"><input type="checkbox" name="mb_options[]" value="'. $id .'" '. $checked .'> '. $title .'</label>'; } } wp_reset_postdata(); } function save_meta_box_product($post_id) { $save_id = 'mb_options'; if(isset($_POST[$save_id])) { update_post_meta($post_id, $save_id, $_POST[$save_id]); } else { delete_post_meta($post_id, $save_id); } } add_action('save_post', 'save_meta_box_product');

functions.phpに追加するコードです。
紐付けたいカスタム投稿に合わせて、「product」「option」と記載されている箇所を適宜置換してください。
以下、ポイントとなる部分を抜き出して解説します。

function add_meta_box_product() { add_meta_box( 'meta_box_product', '選択可能なオプション', 'meta_box_product_callback', array('product'), 'normal' ); } add_action('admin_menu', 'add_meta_box_product');

カスタムフィールドを表示するための処理になります。「add_meta_box」関数に各種引数を設定しています。

第一引数に指定している「meta_box_product」は、編集画面内に埋め込むカスタムフィールドのdiv要素に設定するID名となります。
(今回のサンプルでは設定のみでIDは使用していません)

第二引数に指定している「選択可能なオプション」は、編集画面内に表示されるラベル名となります。

第三引数に指定している「meta_box_product_callback」は、カスタムフィールドの入力項目を記述するための関数名となります。
(関数の内容は後述します)

第四引数に指定している「array('product')」は、このカスタムフィールドを表示する投稿タイプのスラッグとなります。今回は「product」というスラッグ名のカスタム投稿で表示するようにしています。

function meta_box_product_callback() { global $post; $options = get_post_meta($post->ID, 'mb_options', true); $args = array( 'post_type' => 'option', 'posts_per_page' => '-1' ); $the_query = new WP_Query($args); if($the_query->have_posts()) { while($the_query->have_posts()) { $the_query->the_post(); $title = get_the_title(); $id = get_the_ID(); $checked = ''; if(!empty($options) && in_array($id, $options)) { $checked = 'checked="checked"'; } echo '<label style="margin: 0px 2em 0px 0px;"><input type="checkbox" name="mb_options[]" value="'. $id .'" '. $checked .'> '. $title .'</label>'; } } wp_reset_postdata(); }

カスタムフィールドの入力項目を表示するための処理です。
この関数の中で「echo」関数などで出力したhtmlが投稿画面に表示されます。

今回、カスタムフィールドとして保存するオプションの選択内容は「mb_options」というidになります。
「get_post_meta($post->ID, 'mb_options', true);」によって、既に選択されているオプションのスラッグ名が配列形式で取得できます。

カスタム投稿「オプション」の記事データを「WP_Query」関数で取得し、ループで繰り返しながら「echo」関数でチェックボックスを出力していきます。
その際、既に選択済みのオプションであるかをチェックし、選択済みであれば「checked="checked"」属性を付与しています。

関連付けたカスタム投稿を表示する

<?php $options = get_post_meta($post->ID, 'mb_options', true); $args = array( 'post_type' => 'option', 'post__in' => $options ); $the_query = new WP_Query($args); if($the_query->have_posts()) { while($the_query->have_posts()) { $the_query->the_post(); $title = get_the_title(); $link = get_the_permalink(); ?> <p><a href="<?php echo $link; ?>"><?php echo $title; ?></a></p> <?php } } wp_reset_postdata(); ?>

関連付けたカスタム投稿を表示するときの処理です。
一般的なカスタムフィールドを取り扱うときと同じ使い方で紐付けた投稿の記事が取得できます。

「WP_Query」関数のパラメーターの一つである「post__in」に、選択済みオプションのスラッグ名を設定することで、選択されている投稿だけを取得できます。

ご質問など受け付けています

記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。

ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。