【WordPress】投稿一覧ページにカスタム並び順をドラッグ&ドロップで実装する方法

【WordPress】投稿一覧ページにカスタム並び順をドラッグ&ドロップで実装する方法 WordPress

WordPressでは通常、投稿一覧は公開日やタイトルなどで自動的に並びますが、管理画面で直感的に並び順を変更したいというケースもあります。特にカスタム投稿タイプでは「表示順を自由に変更したい」というニーズが高く、ドラッグ&ドロップによる並び替えが非常に便利です。

この記事では、管理画面でドラッグ&ドロップによる投稿の並び順を実装する方法を解説します。

ステップ1:投稿に「menu_order」サポートを追加する

まず、対象の投稿タイプ(例:postnews)に page-attributes をサポートさせ、menu_orderで並び順を管理できるようにします。

function add_menu_order_support() {
  add_post_type_support('post', 'page-attributes');
  // カスタム投稿タイプにも追加可能
  // add_post_type_support('news', 'page-attributes');
}
add_action('init', 'add_menu_order_support');

ステップ2:並び順を反映するための並び替え条件を指定

pre_get_posts フックを使い、管理画面での投稿一覧を menu_order による並び順に変更します。

function set_admin_order_by_menu_order($query) {
  if (is_admin() && $query->is_main_query() && $query->get('post_type') === 'post') {
    $query->set('orderby', 'menu_order');
    $query->set('order', 'ASC');
  }
}
add_action('pre_get_posts', 'set_admin_order_by_menu_order');

この処理により、投稿一覧が menu_order順で表示されます。

ステップ3:管理画面にドラッグ&ドロップ機能を追加

以下のコードを functions.php に追加して、JavaScriptによる並び替えUIを管理画面に挿入します。

function enqueue_drag_drop_script($hook) {
  if ($hook !== 'edit.php') return;

  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('custom-order-script', get_template_directory_uri() . '/js/custom-order.js', array('jquery', 'jquery-ui-sortable'), null, true);

  // Ajax用データ
  wp_localize_script('custom-order-script', 'customOrderAjax', array(
    'ajax_url' => admin_url('admin-ajax.php'),
    'nonce'    => wp_create_nonce('custom_order_nonce'),
  ));
}
add_action('admin_enqueue_scripts', 'enqueue_drag_drop_script');

次に、テーマディレクトリに js/custom-order.js を作成し、以下のコードを記述します。

jQuery(document).ready(function ($) {
  var $tbody = $('tbody');

  $tbody.sortable({
    items: 'tr',
    cursor: 'move',
    update: function () {
      var order = [];
      $tbody.find('tr').each(function (i, el) {
        var id = $(el).attr('id').replace('post-', '');
        order.push(id);
      });

      $.post(customOrderAjax.ajax_url, {
        action: 'save_custom_order',
        order: order,
        nonce: customOrderAjax.nonce
      });
    }
  });
});

ステップ4:並び順を保存するAjax処理を追加

Ajaxで送信された並び順を保存するため、functions.phpに以下の処理を追加します。

function save_custom_order() {
  check_ajax_referer('custom_order_nonce', 'nonce');

  if (!current_user_can('edit_posts')) {
    wp_send_json_error('許可されていません');
  }

  $order = isset($_POST['order']) ? $_POST['order'] : array();

  foreach ($order as $menu_order => $post_id) {
    wp_update_post(array(
      'ID'         => intval($post_id),
      'menu_order' => intval($menu_order),
    ));
  }

  wp_send_json_success('並び順を更新しました');
}
add_action('wp_ajax_save_custom_order', 'save_custom_order');

ステップ5:並び順の見た目を調整する(オプション)

並び替えを明確にするため、管理画面の投稿一覧に IDmenu_order列を追加すると便利です。

function add_menu_order_column($columns) {
  $columns['order'] = '順番';
  return $columns;
}
add_filter('manage_posts_columns', 'add_menu_order_column');

function show_menu_order_column($column_name, $post_id) {
  if ($column_name === 'order') {
    echo get_post_field('menu_order', $post_id);
  }
}
add_action('manage_posts_custom_column', 'show_menu_order_column', 10, 2);

まとめ

WordPress管理画面でドラッグ&ドロップによる並び替えを実装することで、投稿の表示順を自由に制御できるようになります。
とくにカスタム投稿タイプやトップページに表示する特定記事の順序管理に効果的です。

menu_orderを利用すれば、テンプレート側でも簡単に並び順を取得できるため、フロントと管理両面で一貫性のある出力が可能になります。