WordPressにて、
- カスタマイズしたテーマを利用し、テイストを崩したくない
- Related Postsを表示したいけど、表示するpostをWP管理画面で指定したい
- 表示するpostを指定しない場合は、カテゴリーから
という要望があり、Related postsを簡単に設定する方法を考える。
使うプラグイン
- CMB2 ( https://wordpress.org/plugins/cmb2/ )
- CMB2 Attached Posts Field ( https://github.com/CMB2/cmb2-attached-posts )
使い方
1. 上記のプラグインを有効にする
2. CMB2 Attached Post Field のexampleを参考に、こんな感じで functions.php に
function cmb2_attached_posts_field_metaboxes_post() {
$example_meta = new_cmb2_box( array(
'id' => 'cmb2_attached_posts_field',
'title' => 'Related Articles',
'object_types' => array( 'post' ), // Post type
'context' => 'normal',
'priority' => 'high',
'show_names' => false, // Show field names on the left
) );
$example_meta->add_field( array(
'name' => 'Attached Posts',
'desc' => 'Drag posts from the left column to the right column to attach them to this page.<br />You may rearrange the order of the posts in the right column by dragging and dropping.',
'id' => 'attached_posts',
'type' => 'custom_attached_posts',
'column' => true, // Output in the admin post-listing as a custom column. https://github.com/CMB2/CMB2/wiki/Field-Parameters#column
'options' => array(
// 'show_thumbnails' => true, // Show thumbnails on the left
'filter_boxes' => true, // Show a text box for filtering the results
'query_args' => array(
'posts_per_page' => 10,
'post_type' => 'post',
), // override the get_posts args
),
) );
}
function cmb2_attached_posts_field_metaboxes_package() {
$example_meta = new_cmb2_box( array(
'id' => 'cmb2_attached_packages_field',
'title' => 'Related Packages',
'object_types' => array( 'package' ), // Post type
'context' => 'normal',
'priority' => 'high',
'show_names' => false, // Show field names on the left
) );
$example_meta->add_field( array(
'name' => 'Attached Packages',
'desc' => 'Drag posts from the left column to the right column to attach them to this page.<br />You may rearrange the order of the posts in the right column by dragging and dropping.',
'id' => 'attached_packages',
'type' => 'custom_attached_posts',
'column' => true, // Output in the admin post-listing as a custom column. https://github.com/CMB2/CMB2/wiki/Field-Parameters#column
'options' => array(
'show_thumbnails' => true, // Show thumbnails on the left
'filter_boxes' => true, // Show a text box for filtering the results
'query_args' => array(
'posts_per_page' => 10,
'post_type' => 'package',
), // override the get_posts args
),
) );
}
add_action( 'cmb2_init', 'cmb2_attached_posts_field_metaboxes_post' );
add_action( 'cmb2_init', 'cmb2_attached_posts_field_metaboxes_package' );
post typeはcustom post typeでも使えるようにしておくと便利か。
このプラグインでは、idで指定したmeta_name (上記の例だと attached_posts, attached_packages)に、serializeされたarrayで post idが保存される。
3. 表示するところ(例えばsingle.php)に、
<?php
if( $post->post_type == 'post'){
$numberposts = 3;
$section_name = 'Related Posts';
} elseif( $post->post_type == 'package'){
$numberposts = 3;
$section_name = 'Related Packages';
}
?>
<h1><?php echo $section_name; ?></h1>
<div class="items">
<?php
// get related posts
$attached_posts = get_post_meta( get_the_ID(), 'attached_posts', true );
if( is_array( $attached_posts ) && sizeof( $attached_posts) > 0 ){
$args = array(
'post_type' => $post->post_type,
'post__in' => $attached_posts,
'orderby' => 'rand',
'numberposts' => $numberposts
);
}
else {
// get related posts by category
$cats = get_the_category();
$args = array(
'post_type' => $post->post_type,
'post__not_in' => array( get_the_ID() ),
'orderby' => 'rand',
'posts_per_page' => $numberposts,
'cat' => $cats[0]->term_id,
);
}
$the_query = new WP_Query( $args );
while ( $the_query->have_posts() ) :
$the_query->the_post();
if( $post->post_type == 'post'){
get_template_part('content', 'post_box');
}
elseif( $post->post_type =='package'){
get_template_part('content', 'package_box');
}
endwhile;
wp_reset_postdata();
?>
</div>
のようにしておく。contentはtemplate参照。
the_content hookを使うとrecursiveになっちゃう場合があるのでオススメしない。別途hookを定義すると良いかも。
