web-dev-qa-db-ja.com

カスタムフィールドによるカスタム投稿タイプ管理領域の自動ソート

将来の予定を表示するためのカスタム投稿タイプを作成しました。予定の日付はカスタムフィールドに格納されています(YYYY/MM/DD形式)。このカスタム投稿タイプの管理画面を、イベント日のカスタムフィールドで自動的に並べ替えるようにします。

MikeSchnickelの優れた tutorial 「並べ替え」列の作成について試したところで、私は彼が使用しているparse_queryフィルタに似たものを使用する必要があることがわかった。しかし、私はそれを自分のニーズに合わせることはできないようです。

私はこのようにワードプレスをカスタマイズすることはかなり新しいので、いくつかの簡単なガイダンスは大いに感謝されるでしょう!

これは、カスタムタイプの投稿(gs_events)を登録し、カスタムフィールド(event_date)にメタボックスを追加し、管理画面にカスタム列を設定するための私のコードです。

add_action('init', 'my_custom_init');

function my_custom_init() {
  $labels = array(
    'name' => _x('Events', 'post type general name'),
    'singular_name' => _x('Event', 'post type singular name'),
    'add_new' => _x('Add New', 'event'),
    'add_new_item' => __('Add New Event'),
    'edit_item' => __('Edit Event'),
    'new_item' => __('New Event'),
    'view_item' => __('View Event'),
    'search_items' => __('Search Events'),
    'not_found' =>  __('No events found'),
    'not_found_in_trash' => __('No events found in Trash'), 
    'parent_item_colon' => ''
  );
  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'query_var' => true,
    'rewrite' => array('slug' => 'events'),
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => 5,
    'supports' => array('title','editor','thumbnail','comments')
  ); 
  register_post_type('gs_events',$args);
}

register_taxonomy("Location", array("gs_events"), array("hierarchical" => true, "label" => "Cities", "singular_label" => "City", "rewrite" => true));

add_action("admin_init", "admin_init");

function admin_init(){
  add_meta_box("event_date-meta", "Event Date", "event_date", "gs_events", "side", "high");
}

function event_date(){
  global $post;
  $custom = get_post_custom($post->ID);
  $event_date = $custom["event_date"][0];
  ?>
  <label>Date:</label>
  <input name="event_date" value="<?php echo $event_date; ?>" />
  <?php
}

add_action('save_post', 'save_details');

function save_details(){
  global $post;
  update_post_meta($post->ID, "event_date", $_POST["event_date"]);
}

add_action("manage_posts_custom_column",  "events_custom_columns");
add_filter("manage_edit-gs_events_columns", "events_edit_columns");

function events_edit_columns($columns){
  $columns = array(
    "cb" => "<input type=\"checkbox\" />",
    "title" => "Venue",
    "location" => "Location",
    "event_date" => "Date",
  );

  return $columns;
}
function events_custom_columns($column){
  global $post;

  switch ($column) {
    case "event_date":
      $custom = get_post_custom();
      echo $custom["event_date"][0];
      break;
    case "location":
      echo get_the_term_list($post->ID, 'Location', '', ', ','');
      break;
  }
}

そして、私はMike Schnickelsの前述のチュートリアルからこのコードの修正を追加する必要があると考えていますが、この場合それをどのように実装するのかわからない...

add_filter( 'parse_query', 'sort_movie_by_meta_value' );
function sort_movie_by_meta_value($query) {
    global $pagenow;
    if (is_admin() && $pagenow=='edit.php' &&
            isset($_GET['post_type']) && isset($_GET['post_type'])=='movie' && 
            isset($_GET['sortby'])  && $_GET['sortby'] !='None')  {
        $query->query_vars['orderby'] = 'meta_value';
        $query->query_vars['meta_key'] = $_GET['sortby'];
    }
}
5
George

イベントのメタフィールドの日付を文字列ではなくunix-timestampとして保存するのではなく、人生を自分では困難にしすぎるでしょう。日付の比較が非常に簡単になります。

YYYY/MM/DD形式をUNIXタイムスタンプに変換する方法の例を示します。

$date = '2010/09/22';
$dateParts = explode('/', trim($date));
if (count($dateParts) == 3) {
    $timestamp = mktime(0, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0]);
} else {
    $timestamp = 0; 
    // The input value is dodgy, therefore the timestamp is set to 0, which is 
    // effectively 1970-01-01T00:00:00Z.
}

ユーザーの編集および表示用に再度変換するには、次のように簡単です。

$displayValue = date('Y/m/d', $timestamp);

Gs_event_dateのように、カスタムフィールドにもっと具体的な名前を付けることをお勧めします。

それが終わったら、フィルタを作成します。

function gs_events_pre_get_posts($query) {

    // Note: Use the $pagenow global for finer grained checking, 
    // if you want to. There are many examples out there.

    // Your question pertains to admin use only...

    if (is_admin()) {

        // Present the posts in your meta_key field's order in admin

        if (isset($query->query_vars['post_type'])) {
            if ($query->query_vars['post_type'] == 'gs_events') {

                $query->set('meta_key', 'gs_event_date');
                $query->set('orderby', 'meta_value');
                $query->set('order', 'ASC');

                // ...and if you only want your future events to be 
                // displayed in admin, you can uncomment the following:

                // $query->set('meta_compare', '>=');
                // $query->set('meta_value', time());

                // Note: The use of time() is quick-and-dirty here, 
                // in reality you'll need to adjust the timezone, 
                // check server-time vs local time, etc.
            }
        }
    }
}

フィルタを追加してください...

add_filter('pre_get_posts' , 'gs_events_pre_get_posts');
5
Werner