プラグインなしで投稿・固定ページ一覧のカラム順序を自由に変更する方法

Cocoonカスタマイズ集
この記事は約13分で読めます。
記事内に広告が含まれています。

はじめに

WordPressの管理画面で投稿や固定ページの一覧を見ていると、デフォルトのカラム順序では使いにくいことがあります。
特に「作成者」や「カテゴリー」など、テーマやプラグインで追加された独自カラムも含めて、自由に並び替えたい場合があります。

そこで、プラグイン「Admin Columns」などを使用せずに、投稿・固定ページの一覧カラムをドラッグ操作で並び替える機能を追加します。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// 表示オプションにメニューを追加
add_filter('screen_settings', function ($html, $screen) {
  if (!in_array($screen->id, ['edit-post', 'edit-page'])) {
    return $html;
  }

  $post_type = $screen->post_type;

  // 現在のカラム一覧を取得
  require_once ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php';
  $table = new WP_Posts_List_Table();
  $columns = $table->get_columns();

  // チェックボックス列は並び替え対象から除外
  if (isset($columns['cb'])) {
    unset($columns['cb']);
  }

  // 保存されている並び順を取得
  $saved = get_option("my_columns_order_$post_type");
  if (!is_array($saved)) {
    $saved = array_keys($columns);
  }

  // 保存された順序を反映した配列を構築
  $display_order = [];
  $temp = $columns;

  foreach ($saved as $key) {
    if (isset($temp[$key])) {
      $display_order[$key] = $temp[$key];
      unset($temp[$key]);
    }
  }

  $display_order = array_merge($display_order, $temp);

  ob_start();
  ?>
  <p style="margin-top: 15px;">ドラッグ&ドロップでカラムの並び順を変更できます。</p>
  <ul id="custom-column-sortable">
    <?php foreach ($display_order as $key => $label): ?>
      <?php $text_label = wp_strip_all_tags($label); ?>
      <li class="ui-state-default" data-col="<?= esc_attr($key); ?>">
        <span class="grip-icon">⋮⋮</span>
        <?= esc_html($text_label); ?>
      </li>
    <?php endforeach; ?>
  </ul>
  <div class="custom-column-action-area">
    <button id="column-sort-save" class="button button-primary">設定を保存</button>
    <button id="column-sort-reset" class="button button-link-delete">リセット</button>
  </div>
  <?php

  return $html . ob_get_clean();
}, 10, 2);


// カラムの並び順を保存するAjax処理
add_action('wp_ajax_save_columns_order', function () {
  // nonceチェック
  check_ajax_referer('columns_order_action', 'columns_order_nonce');

  // 権限チェック
  if (!current_user_can('manage_options')) {
    wp_send_json_error();
  }

  $post_type = sanitize_key($_POST['post_type']);
  $order = isset($_POST['order']) ? array_map('sanitize_text_field', $_POST['order']) : [];

  // 投稿または固定ページ以外は除外
  if (!in_array($post_type, ['post', 'page'])) {
    wp_send_json_error();
  }

  update_option("my_columns_order_$post_type", $order);

  set_transient('my_admin_notice', [
    'type'    => 'success',
    'message' => 'カラム順序を保存しました。',
  ], 30);

  wp_send_json_success();
});


// カラムの並び順をリセットするAjax処理
add_action('wp_ajax_reset_columns_order', function () {
  // nonceチェック
  check_ajax_referer('columns_order_action', 'columns_order_nonce');

  // 権限チェック
  if (!current_user_can('manage_options')) {
    wp_send_json_error();
  }

  $post_type = sanitize_key($_POST['post_type']);

  // 投稿または固定ページ以外は処理対象外
  if (!in_array($post_type, ['post', 'page'])) {
    wp_send_json_error();
  }

  delete_option("my_columns_order_$post_type");

  set_transient('my_admin_notice', [
    'type'    => 'success',
    'message' => 'カラム順序を初期状態に戻しました。',
  ], 30);

  wp_send_json_success();
});


/**
 * 投稿・固定ページ一覧に保存されたカラムの並び順を反映
 *
 * @param array $columns カラム配列
 * @return array 並び替え後のカラム配列
 */
if (!function_exists('apply_columns_order')):
function apply_columns_order($columns) {
  // 管理画面スクリーン情報を取得
  $screen = get_current_screen();
  $post_type = $screen->post_type ?? '';

  // 保存されている並び順を取得
  $order = get_option("my_columns_order_$post_type");

  if (!is_array($order)) {
    return $columns;
  }

  $new = [];

  // チェックボックス列が存在する場合は先頭に固定
  if (isset($columns['cb'])) {
    $new['cb'] = $columns['cb'];
    unset($columns['cb']);
  }

  // 保存された順序に従ってカラムを再配置
  foreach ($order as $column) {
    if (isset($columns[$column])) {
      $new[$column] = $columns[$column];
      unset($columns[$column]);
    }
  }

  // 残りのカラムを末尾に結合
  $new = array_merge($new, $columns);

  return $new;
}
endif;


// 管理画面一覧にカラムを追加
add_filter('manage_posts_columns', 'apply_columns_order', 999);
add_filter('manage_pages_columns', 'apply_columns_order', 999);


// 通知メッセージを出力
add_action('admin_notices', function () {
  $screen = get_current_screen();

  // 投稿・固定ページ一覧画面以外は処理対象外
  if (!in_array($screen->id, ['edit-post', 'edit-page'])) {
    return;
  }

  if ($notice = get_transient('my_admin_notice')) {
    echo '<div class="notice notice-' . esc_attr($notice['type']) . ' is-dismissible"><p>' . esc_html($notice['message']) . '</p></div>';
    delete_transient('my_admin_notice');
  }
});


// 管理画面用JS/CSSを追加
add_action('admin_enqueue_scripts', function ($hook_suffix) {
  if ($hook_suffix !== 'edit.php' && $hook_suffix !== 'edit-pages.php') {
    return;
  }

  wp_localize_script('jquery-ui-sortable', 'columnSettings', [
    'ajaxurl' => admin_url('admin-ajax.php'),
    'nonce'   => wp_create_nonce('columns_order_action')
  ]);

  ob_start();
  ?>
  jQuery(function ($) {
    /**
     * Sortableを初期化する
     */
    function initSortable() {
      $('#custom-column-sortable').sortable({
        placeholder: 'ui-state-highlight',
        forcePlaceholderSize: true
      });
    }

    initSortable();

    // 画面オプションのトグルが開かれた場合
    $('#show-settings-link').on('click', function () {
      setTimeout(initSortable, 10);
    });

    // 現在のリストの並び順を配列に格納
    $('#column-sort-save').on('click', function () {
      var order = [];

      $('#custom-column-sortable li').each(function () {
        order.push($(this).data('col'));
      });

      var post_type = $('body').hasClass('post-type-post') ? 'post' : 'page';

      // Ajaxで並び順を送信
      $.post(columnSettings.ajaxurl, {
        action: 'save_columns_order',
        post_type: post_type,
        order: order,
        columns_order_nonce: columnSettings.nonce
      }, function (res) {
        if (res.success) {
          location.reload();
        } else {
          console.error(res);
        }
      }).fail(function (jqXHR, textStatus, errorThrown) {
        console.error(textStatus, errorThrown);
      });
    });

    // 「リセット」ボタンクリック
    $('#column-sort-reset').on('click', function () {
      if (!confirm('カラムの並び順をデフォルトに戻しますか?')) {
        return;
      }

      var post_type = $('body').hasClass('post-type-post') ? 'post' : 'page';

      // Ajaxを使ってデフォルト設定にリセット
      $.post(columnSettings.ajaxurl, {
        action: 'reset_columns_order',
        post_type: post_type,
        columns_order_nonce: columnSettings.nonce
      }, function (res) {
        if (res.success) {
          location.reload();
        }
      });
    });
  });
  <?php

  wp_enqueue_script('jquery-ui-sortable');
  wp_add_inline_script('jquery-ui-sortable', ob_get_clean());

  ob_start();
  ?>
  #custom-column-sortable {
    background-color: #fff;
    border: 1px solid #ccd0d4;
    border-radius: 4px;
    max-height: 300px;
    max-width: 400px;
    overflow-y: auto;
    padding: 10px;
  }

  #custom-column-sortable li {
    align-items: center;
    background-color: #f6f7f7;
    border: 1px solid #dcdcde;
    border-radius: 3px;
    cursor: move;
    display: flex;
    margin-bottom: 5px;
    padding: 8px 12px;
  }

  #custom-column-sortable li .grip-icon {
    color: #8c8f94;
    letter-spacing: -1px;
    margin-right: 8px;
  }

  .custom-column-action-area {
    align-items: center;
    display: flex;
    gap: 10px;
    margin-top: 10px;
  }

  #custom-column-sortable .ui-state-highlight {
    background-color: #f0f6fc;
    border: 1px dashed #2271b1;
    border-radius: 3px;
    height: 36px;
    margin-bottom: 5px;
  }
  <?php

  wp_add_inline_style('wp-admin', ob_get_clean());
});

さいごに

今回紹介した方法を使えば、プラグインを使わずに、投稿や固定ページの一覧カラムを自由にドラッグで並び替えることができます。
テーマやプラグインで追加された独自カラムも含めて、自分好みの順序で管理画面をカスタマイズできるため、作業効率の向上や画面の見やすさを大幅に改善できます。

タイトルとURLをコピーしました