Чтобы добавить пользовательские поля в панель быстрого редактирования (Quick Edit) для произвольного типа записей (Custom Post Type) в WordPress, стандартной функции add_action('quick_edit_custom_box', ...) недостаточно. Нужно пройти 3 основных этапа:
- Вывести поля в хуке
quick_edit_custom_box. - Передать существующие значения из строки таблицы в форму редактирования с помощью JavaScript.
- Сохранить данные в хуке
save_post.
Допустим, у нас есть кастомный (пользовательский) тип записи course. В каждом курсе есть метаполя duration (длительность курса в месяцах, мета-ключ* course_duration) и lessons (количество занятий, мета-ключ* course_lessons). И эти метаполя выведены в сводную таблицу в админке. Чтобы была возможность отредактировать эти данные в этой таблице, не переходя в редактирование самого курса, выведем их в блок Быстрая правка (Quick Edit в англ. варианте перевода). Этот блок в русской версии открывается при клике на пункт "Свойства" в любом типе постов.

*мета-ключ - это наименование поля, по которому в базе данных сохраняется его значение.
Пошаговое п добавление полей в панель быстрого редактирование
1. Вывод поля в интерфейсе Quick Edit
Хук quick_edit_custom_box срабатывает при отрисовке формы быстрого редактирования. В нем проверяем тип записи и вывод HTML-разметку:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | add_action('quick_edit_custom_box', 'add_custom_quick_edit_fields', 10, 2); function add_custom_quick_edit_fields($column_name, $post_type) { // Проверяем, что работаем с нужным типом записи и колонкой if ($post_type !== 'course' || $column_name !== 'duration') { return; } // Обязательно добавляем nonce для безопасности wp_nonce_field('save_quick_edit_course_nonce', 'quick_edit_course_nonce'); ?> <fieldset class="inline-edit-col-right"> <div class="inline-edit-col"> <label> <span class="title">Длительность</span> <span class="input-text-wrap"> <input type="text" name="course_duration" class="course_duration_field" value=""> </span> </label> <label> <span class="title">Занятия</span> <span class="input-text-wrap"> <input type="text" name="course_lessons" class="course_lesson_field" value=""> </span> </label> </div> </fieldset> <?php } |
2. Заполнение полей текущими данными (JavaScript)
Форма Quick Edit создается в DOM один раз и динамически подставляется в выбранную строку. Чтобы заполнить поля актуальными значениями, нужно:
- Вывести данные в колонку таблицы (или скрытый элемент).
- Перехватить клик на кнопку «Быстрое редактирование» с помощью JS.
A. Вывод значений в колонку:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // Добавляем колонку в таблицу записей add_filter('manage_course_posts_columns', function($columns) { $columns['duration'] = 'Длительность'; $columns['lessons'] = 'Занятия'; return $columns; }); // Заполняем колонку значением из meta-data add_action('manage_course_posts_custom_column', function($column_name, $post_id) { if ($column_name === 'duration') { $duration = get_post_meta($post_id, 'course_duration', true); echo '<span class="duration-value">' . esc_html($duration) . '</span>'; } if ( 'lessons' === $column_name) { $lessons = get_post_meta($post_id,'course_lessons',true); if ( '' === $lessons ) { echo '—'; return; } echo '<span class="lessons-value" data-value="' . esc_attr( $lessons ) . '">' . esc_html( $lessons ) . '</span>'; } }, 10, 2); |
B. Скрипт подстановки данных (jQuery):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | add_action('admin_footer-edit.php', 'quick_edit_js_script'); function quick_edit_js_script() { $current_screen = get_current_screen(); if ($current_screen->post_type !== 'course') return; ?> <script type="text/javascript"> jQuery(document).ready(function($) { // Перехватываем стандартную функцию inlineEditPost.edit var $inline_editor = inlineEditPost.edit; inlineEditPost.edit = function(id) { // Вызываем оригинальную функцию WordPress $inline_editor.apply(this, arguments); // Получаем ID записи let postId = 0; if ( typeof id === 'object' ) { postId = parseInt( this.getId( id ), 10 ); } else postId = parseInt( id, 10 ); if ( ! postId ) return; const row = $( '#post-' + postId ); const editRow = $( '#edit-' + postId ); // Course fields. editRow.find( '.course_duration_field' ).val( row.find( '.duration-value' ).data( 'value' ) || ''); editRow.find( '.course_lesson_field' ).val( row.find( '.lessons-value' ).data( 'value' ) || ''); }; }); </script> <?php } |
3. Сохранение данных
Обрабатываем сохранение в хуке save_post:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | add_action('save_post', 'save_quick_edit_course_data'); function save_quick_edit_course_data($post_id) { // Проверки безопасности if (!isset($_POST['quick_edit_course_nonce']) || !wp_verify_nonce($_POST['quick_edit_course_nonce'], 'save_quick_edit_course_nonce')) { return; } if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!current_user_can('edit_post', $post_id)) return; // Сохраняем поле if (isset($_POST['course_duration'])) { update_post_meta($post_id, 'course_duration', sanitize_text_field($_POST['course_duration'])); } if (isset($_POST['course_duration'])) { update_post_meta($post_id, 'course_lessons', sanitize_text_field($_POST['course_lessons'])); } } |
Альтернатива (без написания кода)
Если вы не хотите прописывать всю логику вручную, для добавлений полей в Quick Edit часто используют готовые плагины:
Admin Columns Pro — позволяет в пару кликов добавлять любые мета-поля в колонки и в панель быстрого редактирования.
ACF Extende (Advanced Custom Fields Extended) — расширение для ACF, которое умеет выводить созданные поля ACF прямо в Quick Ed
dit / Bulk Edit.
Возможные проблемы
Здорово, если у вас все пошло хорошо, но возможны и проблемы. Например, дополнительные поля в быстром редактировании у вас совсем не отображаются, а вот столбцы в админке со всеми данными присутствуют.
Если такое происходит, т.е. колонки в админке выводятся, а сама форма Quick Edit пуста, чаще всего проблема заключается в одной из следующих причин:
- Имя колонки не совпадает с аргументом хука: хук
quick_edit_custom_boxпередает имя проверяемой колонки в первом параметре ($column_name). Если в коде стоит жесткое условиеif ($column_name !== 'my_custom_column'), но slug колонки называется иначе (например,course_durationилиduration), разметка просто не отрендерится. - Неверный
$post_typeв проверке: Если внутри колбэка проверяется$post_type, убедитесь, что регистр и имя совпадают с зарегистрированным Custom Post Type (в вашем случаеcourse). - Ошибки инициализации хука: Метод/функция вывода полей должна быть корректно подключена с привязкой 2 аргументов:
add_action('quick_edit_custom_box', array($this, 'render_quick_edit_fields'), 10, 2);(Если не указать2, параметр$post_typeне передастся в функцию). - Скрытие элементов через CSS: WordPress оборачивает быстрое редактирование в определенные классы. Если не используются стандартные обертки WordPress (
<fieldset class="inline-edit-col-right"><div class="inline-edit-col">...), админка может скрыть или некорректно отобразить блок.
А что делать, например, если при нажатии в быстром редактировании на кнопку "Сохранить" крутится значок отправки, но сохранение не происходит?
Возможные ошибки в Quick Edit
Бесконечно вращающийся спиннер при попытке сохранения в Quick Edit говорит о том, что процесс сохранения завершается ошибкой на сервере (PHP/Ajax) или сбоем выполнения JavaScript. В этот момент WordPress отправляет AJAX-запрос, но либо не получает валидный JSON-ответ, либо сервер возвращает ошибку 500 / 400.
Чтобы быстро найти и исправить причину, выполните следующие шаги:
1. Проверьте консоль и Ajax-ответ:
Откройте инструменты разработчика в браузере (клавиша F12 или Ctrl+Shift+I / Cmd+Option+I):
- Перейдите на вкладку Network (Сеть) и фильтруйте по Fetch/XHR.
- Нажмите кнопку Оновити (Сохранить) в форме быстрого редактирования.
- В списке появится запрос к
admin-ajax.php. Нажмите на него и посмотрите вкладку Response (Ответ).
Если там выводится критическая ошибка PHP или заголовок 500 Internal Server Error, вы сразу увидите строку кода, вызвавшую сбой.
2. Проверьте save_post на бесконечный цикл:
Самая распространенная причина «зависания» — вызов wp_update_post() внутри хука save_post без отключения этого же хука. Это вызывает рекурсию, превышение лимита памяти или тайм-аута:
1 2 3 4 5 6 7 8 9 10 | // Неправильно: провоцирует бесконечный цикл add_action('save_post', function($post_id) { // ... wp_update_post([...]); // Снова вызывает save_post! }); // Правильно: перед вызовом нужно отключать и снова включать хук remove_action('save_post', 'my_save_function'); wp_update_post([...]); add_action('save_post', 'my_save_function'); |
А если вы просто обновляете мета-данные (update_post_meta), делать вызов wp_update_post() вовсе не нужно.
3. Исправьте отправку и проверку Nonce
Если проверка Nonce не проходит или код принудительно завершает процесс через die() / wp_die() без ответа, Quick Edit зависает.
Проверьте ваш обработчик сохранения:
- Замените жесткий
wp_die()илиreturnпри отсутствии Nonce на корректный выход, чтобы стандартные поля WordPress продолжали сохраняться. - Убедитесь, что при валидации Nonce вы делаете проверку только тогда, когда мета-поле действительно передается в
$_POST:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | add_action('save_post', 'save_course_quick_edit'); function save_course_quick_edit($post_id) { // Проверяем автосохранение и права if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!current_user_can('edit_post', $post_id)) return; // Проверяем Nonce ТОЛЬКО если поле передано из формы Quick Edit if (isset($_POST['quick_edit_course_nonce'])) { if (!wp_verify_nonce($_POST['quick_edit_course_nonce'], 'save_quick_edit_course_nonce')) { return; } if (isset($_POST['course_duration'])) { update_post_meta($post_id, 'course_duration', sanitize_text_field($_POST['course_duration'])); } if (isset($_POST['course_lessons'])) { update_post_meta($post_id, 'course_lessons', sanitize_text_field($_POST['course_lessons'])); } } } |
4. Проверьте вывод лишнего текста/PHP Notice:
Если где-то в PHP-файлах (например, в functions.php или подключенных классах) есть вывод лишних символов, пробелов до <?php или ошибок/предупреждений PHP Notice, они ломают JSON-ответ от admin-ajax.php.
Временно включите отладку в wp-config.php, чтобы логировать ошибки в файл, а не выводить их в Ajax-ответ:
1 2 3 | define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); // Скрывает вывод ошибок в интерфейс/Ajax |
После этого повторите попытку сохранения и проверьте файл wp-content/debug.log.
Чтобы проверить, успешна ли отладка, откройте Network в F12 и нажмите «Обновить»: запрос admin-ajax.php должен вернуть статус 200 OK, а строчка с курсом в таблице обновляться без перезагрузки страницы.
Еще АJAX явно где-то видит ошибку, если вы просто пропустили какой-то знак в своем php-файле типа точки, запятой, точки с запятой или скобки (знакомо, не так ли?). Или неверно объявили переменную без знака $, и она стала считаться некой строковой константой. Например, так:
1 | update_post_meta( $post_id, 'course_lessons', lessons ); |
Вы передали константу или имя переменной lessons без знака $ перед ней. PHP наталкивается на необъявленную константу, что вызывает Fatal Error / Undefined constant "lessons", из-за чего сервер отдаёт статус 500 Internal Server Error и Ajax-запрос «зависает» намертво.
Исправляем фатальную ошибку с переменной $lessons:
1 2 3 4 5 6 7 8 9 10 | private function save_lessons( int $post_id ): void { if ( ! isset( $_POST['course_lessons'] ) ) return; $lessons = absint( wp_unslash( $_POST['course_lessons'] ) ); // Исправлено: добавляем знак $ к переменной $lessons update_post_meta( $post_id, 'course_lessons', $lessons ); } |
Еще возможный вариант: ошибки - это, когда у вас отслеживается неверно указанный nonce или их два и более, а вы отслеживаете не тот, что нужно при сохранении.
Исправляем проверку Nonce для Quick Edit:
В хуке Quick Edit nonce из обычного метабокса (pc_course_nonce) не отправляется, если вы не добавили скрытый input с этим же именованием в форму быстрого редактирования. Из-за этого условие проверки мгновенно прерывает выполнение методом return, и данные быстрого редактирования вовсе не сохраняются.
Сделайте гибкую проверку nonce с учетом Quick Edit или добавьте fallback:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public function save( int $post_id, WP_Post $post ): void { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; // Проверяем nonce стандартного метабокса ИЛИ встроенный nonce Quick Edit от WordPress $is_valid_nonce = false; if ( isset( $_POST['course_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['course_nonce'] ) ), 'course_save' ) ) { $is_valid_nonce = true; } elseif ( isset( $_POST['_inline_edit'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_inline_edit'] ) ), 'inlineeditnonce' ) ) { $is_valid_nonce = true; } if ( ! $is_valid_nonce ) return; // Permissions. if ( ! current_user_can( 'edit_post', $post_id ) ) return; $this->save_duration( $post_id ); $this->save_lessons( $post_id ); } |
Заключение
Возможно, это не самое нужное действие для админки WordPress, но зато очень удобное, если вы "обросли" метабоксами и не хотите менять значение каждого, переходя каждый раз в редактирование всего поста. Надеюсь, вам был полезен и код, и разбор ошибок. Ну, а если решения не нашлось, то Google и ИИ вам в помощь.
