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を定義すると良いかも。