В wordpress существуют следующие варианты сортировки записей:
- author — сортировать по ID авторов
- content — сортировать по контенту
- date — сортировать по дате создания записи (по умолчанию)
- ID — сортировать по ID записи
- menu_order — сортировать по полю menu_order (используется для постоянных страниц и вложений (картинки, файлы и т.п.))
- mime_type — сортировать по MIME типу (используется для вложений)
- modified — сортировать по дате изменения
- name — сортировать по альтернативному имени (slug)
- rand — случайная сортировка (!создает повышенную нагрузку на БД)
- status — сортировать по статусу
- title — сортировать по названию
- parent — сортировать по ID родителя (parent ID)
- password — сортировать по паролю
- type — сортировать по типу
- comment_count — по количеству комментариев
- meta_value — по значению указанного произвольного поля
- post__in — учитывает порядок указанных ID в параметре include
И направления сортировки: ASC (по порядку) и наоборот DESC.
Но все вышеперечисленные варианты сортировки могут быть не понятны и не удобны конечному заказчику. Например, вполне понятный вариант сортировки по menu_order, на практике не удобно реализовано. Необходимо доработать сортировку. Хорошо что существуют плагины решающие эту проблему.
Post Types Order
Post Types Order установлен более 400 000 раз. Создает отдельную раздел (непонятно зачем), где можно менять местами записи. Также можно менять местами записи перетаскиванием в стандартном разделе, но тут есть одно неудобство — если сделать фильтр по категориям, то перестает работать перетаскивание.
Intuitive Custom Post Order
Intuitive Custom Post Order (200 000) — скажу сразу, этот плагин мне понравился намного больше! В настройках мы выбираем какие типы записей и таксономии хотим сортировать. Сортировка происходит перетаскиванием, сохранять ничего не нужно — все изменения вступают в силу сразу. При фильтрации по категориях сортировка записей продолжает работать. И самое крутое — сортировка таксономий по тому же принципу. Нет необходимости в отдельном плагине.
Еще один плагин — Simple Custom Post Order (100 000 установок) — копия плагина Intuitive Custom Post Order, функционал один в один.
Альтернативный способ сортировки
Но способ drag & drop опять же не всегда удобен, когда, например, много записей и они разбиты на несколько страниц. В этом случае нужно работать с параметром menu_order в контексте поля.
Необходимо организовать следующий функционал:
1. Добавляем записям редактирование параметра menu_order
// Menu_order for posts add_action( 'admin_init', 'posts_order_wpse_91866' ); function posts_order_wpse_91866() { add_post_type_support( 'post', 'page-attributes' ); }
2. Выводим колонку menu_order в панели редактирования записей. Создаем функцию заполняющую ее. Делаем функцию сортировки по колонке (это почему-то не работает).
// Добавляем колонку menu_order function add_new_header_text_column($header_text_columns) { $header_text_columns['menu_order'] = "Порядок"; return $header_text_columns; } add_action('manage_posts_columns', 'add_new_header_text_column'); // Заполнение колонки menu_order function show_order_column($name){ global $post; switch ($name) { case 'menu_order': $order = $post->menu_order; echo $order; break; default: break; } } add_action('manage_posts_custom_column','show_order_column'); // Сортировка по колонке menu_order add_filter( 'manage_edit-post_sortable_columns', 'true_sort_prosmotr' ); // manage_edit-{тип поста}_sortable_columns add_action( 'pre_get_posts', 'true_orderby_prosmotr' ); function true_sort_prosmotr( $columns ) { $columns['menu_order'] = 'menu_order'; //Здесь можно сделать любую колонку несортируемой //unset($columns['date']); return $columns; } function true_orderby_prosmotr( $query ) { if( ! is_admin() ) // так как сортировка будет осуществляться только в админке return; $orderby = $query->get( 'orderby'); if( 'views' == $orderby ) { $query->set('orderby','menu_order'); } }
3. Функция быстрого изменения menu_order. В принципе, благодаря первому пункту, menu_order будет доступен в панели быстрого редактирования. Но это не самый быстрый и удобный способ. Здесь необходимо создать функцию обновления menu_order ajax (как это реализовано при обновлении цены здесь). Данный функционал создал — читать ниже.
4. Переопределим сортировку в циклах вывода сайтов.
// Меняем сортировку по сайту if( !is_admin() ) { function custom_type_post_main($query) { $query->set('orderby', 'menu_order' ); $query->set('order', 'ASC' ); } add_action('pre_get_posts','custom_type_post_main'); }
Если в каких-то местах не будет сортировать по menu_order, надо смотреть вывод и прописывать ‘orderby’ => ‘menu_order’.
Быстрое изменение menu_order
Немного изменяем функцию заполнения значений колонки
function show_order_column($name){ global $post; switch ($name) { case 'menu_order': echo ''; break; default: break; } } add_action('manage_posts_custom_column','show_order_column');
Подключаем функцию и скрипт обновления.
// Ajax обновление поля menu_order function addsitesortposts() { wp_enqueue_script( 'ajax-post-update', plugins_url('/ajax-post-update.js', __FILE__), array('jquery'), null, true ); } add_action( 'admin_enqueue_scripts', 'addsitesortposts' ); function updatePrice_callback(){ $my_post = array(); $my_post['ID'] = $_POST['product_id']; $my_post['menu_order'] = $_POST['price_val']; //$my_post['post_content'] = 'новый контент записи'; // Можно добавлять и другие параметры // Обновляем данные в БД wp_update_post( wp_slash($my_post) ); die(); } if( is_admin() ) { add_action('wp_ajax_updatePrice', 'updatePrice_callback'); }
Скрипт ajax-post-update.js:
jQuery(function($){ $('.field_update').blur(function(){ this_price = $(this); $.ajax({ type:'POST', url:ajaxurl, data:'action=updatePrice&price_val=' + this_price.val() + '&product_id=' + this_price.attr('data-id'), beforeSend:function(xhr){ this_price.attr('readonly','readonly').next().html('Сохраняю...'); }, success:function(results){ this_price.removeAttr('readonly').next().html('<span style="color:#0FB10F">Сохранено</span>'); } }); }); });[site-socialshare]