スポンサーリンク

WordPressの管理画面におけるカスタム投稿一覧画面のカスタマイズ

Web系

ここでは下記の条件を満たすカスタマイズを行います。

  • カスタムタクソノミーとカスタムフィールドを持つカスタム投稿
  • 一覧にカスタムタクソノミーとカスタムフィールドのカラム(列)を追加する
  • 各カラムでのソートが出来るようにする
  • 各カスタムタクソノミーとカスタムフィールドでの絞り込み検索が出来るようにする
  • カスタマイズはfunctions.phpに記述する

サンプルとして定義するカスタム投稿・カスタムタクソノミー・カスタムフィールドの名称およびスラッグは下記の通りとします。

名称スラッグ
カスタム投稿イベントevent
カスタムタクソノミー地域area
カスタムフィールド主催organizer

function.php

/*一覧のカラム追加*/
function event_list_columns_name( $columns ) {
  $columns['area'] = '地域';
  $columns['organizer'] = '主催者';
  return $columns;
}
add_filter( 'manage_edit-event_columns', 'event_list_columns_name' );

/*一覧のカラムの列挙順指定*/
function sort_event_list_columns( $columns ){
  $columns = array(
    'area' => '地域',
    'organizer' => '主催者',
  );
  return $columns;
}
add_filter( 'manage_edit-event_columns', 'sort_event_list_columns');

/*一覧のカラムのデータ取得*/
function event_list_columns_data( $column_name, $post_id ) {
  switch ( $column_name ) {
    case 'area':
      $terms = get_the_terms( $post_id, 'area' );
      foreach ( $terms as $term ) {
        $stitle .= $term->name.'<br>'; //複数選択された場合は全て出力される
      }
      break;
    case 'organizer':
      $metas = get_post_meta( $post_id );
      $stitle = $metas['organizer'][0];
      break;
    default:
      //
    }
 
  if ( isset( $stitle ) && $stitle ) {
    //echo esc_attr( $stitle ); //エスケープして出力する場合
    echo $stitle;
  } else {
    echo __('None');
  }
}
add_action( 'manage_event_posts_custom_column', 'event_list_columns_data', 10, 2 );

/*一覧のカラムのソート機能提供
*  投稿一覧ソート機能(タクソノミーソート対応)
*  参考:https://qiita.com/uto-usui/items/6a4987fd1e65bbc22ad6
*/
function event_sortable_columns($sort_column) {
  $sort_column['area'] = 'area';
  $sort_column['organizer'] = 'organizer';
  return $sort_column;
}
function event_orderby_columns( $vars ) {
  if (isset($vars['orderby']) && 'organizer' == $vars['orderby']) {
    $vars = array_merge($vars, array(
      'orderby' => 'meta_value',
      'meta_key' => 'organizer'
    ));
  }
  if (isset($vars['orderby']) && 'area' == $vars['orderby']) {
    $vars = array_merge($vars, array(
      'taxonomy' => 'area',
      'orderby' => 'name',
    ));
  }
  return $vars;
}
add_filter( 'manage_edit-event_sortable_columns', 'event_sortable_columns' ); // manage_edit-[post_type]_sortable_columns
add_filter( 'request', 'event_orderby_columns' );

/* 一覧でタクソノミーおよびカスタムフィールドによる絞り込み */
function add_post_taxonomy_restrict_filter() {
  global $post_type;
  if ( 'event' == $post_type ) {
      ?>
      <select name="area">
          <option value="">全ての地域</option>
          <?php
          $terms = array_reverse(get_terms('area'));
          foreach ($terms as $term) { ?>
              <option value="<?php echo $term->slug; ?>"<?php if(isset($_GET['area']) && $_GET['area'] == $term->slug){echo ' selected'}?>><?php echo $term->name; ?></option>
          <?php } ?>
      </select>
      <?php
      echo '<input type="text" name="organizer" value="'. get_query_var('organizer'). '" placeholder="主催者" />';
      ?>
      <?php
  }
}
add_action( 'restrict_manage_posts', 'add_post_taxonomy_restrict_filter' );

/* 一覧の文字列検索フィールドで主催者フィールドを検索対象に含める */
function posts_where_organizer($where) {
  global $wpdb;
  global $post_type;
  //管理画面でのみ実行
  if( is_admin() && 'event' == $post_type ) {
  	$value = get_query_var('organizer');
		if( !empty($value) ) {
			//検索条件にカスタムフィールド「organizer」の値を追加
			$where .= $wpdb->prepare(" AND EXISTS ( SELECT * FROM {$wpdb->postmeta} as m
				WHERE m.post_id = {$wpdb->posts}.ID AND m.meta_key = 'organizer' AND m.meta_value like %s )",
				"%{$value}%" );
		}
	}
	return $where;
};
add_filter('posts_where', 'posts_where_organizer');

結構な頻度で似たようなカスタマイズをしているので、出来ればプラグイン化したいと思っています。