Вопрос или проблема
Я использую поле ACF для создания пользовательского слога для типа поста. Все работает и сохраняется правильно в базе данных. Единственное, значение поля ссылки в админке не обновляется при публикации. Мне нужно перезагрузить страницу, чтобы увидеть новый пользовательский слог. При сохранении значение поля ссылки для нового слога обновляется мгновенно.
Есть ли способ обновить показанное значение в админке даже при первой публикации? Пожалуйста, обратите внимание, что все работает правильно, это просто косметическая ошибка, которую я не могу исправить без того, чтобы конечному пользователю пришлось перезагрузить страницу.
Вот мой код на данный момент:
add_action( 'save_post', 'wpse105926_save_post_callback');
function wpse105926_save_post_callback( $post_id) {
$post = get_post($post_id);
$target_post_types = ['song', 'album'];
if (in_array($post->post_type, $target_post_types)) {
// отключить эту функцию, чтобы предотвратить бесконечный цикл
remove_action( 'save_post', 'wpse105926_save_post_callback' );
$artist_field = ($post->post_type === 'song') ? get_field('song_artist', $post->ID) : get_field('album_artist', $post->ID);
if (is_array($artist_field) && !empty($artist_field))
$artist_slug = isset($artist_field[0]->post_name) ? $artist_field[0]->post_name : '';
elseif (is_object($artist_field))
$artist_slug = isset($artist_field->post_name) ? $artist_field->post_name : '';
else $artist_slug = '';
$post_title = sanitize_title_with_dashes($post->post_title);
if ($artist_slug !== '') $slug = "{$post_title}-{$artist_slug}";
else $slug = "{$post_title}";
// обновить слог поста
wp_update_post( array(
'ID' => $post_id,
'post_name' => $slug // сделай свое дело здесь
));
// перезапустить эту функцию
add_action( 'save_post', 'wpse105926_save_post_callback' );
}
}
Я нашел этот пост с объяснением, но это кажется странным, потому что при последующих сохранениях это работает мгновенно: Слог поста, измененный с помощью кода, не отображается в редакторе, когда пост опубликован
Ответ или решение
Проблема, с которой вы столкнулись, заключается в том, что пользовательский слаг (slug) вашего поста обновляется в базе данных, но не отображается в редакторе Gutenberg до тех пор, пока вы не обновите страницу. Давайте рассмотрим, почему это происходит и как можно улучшить поведение вашего кода.
Причины проблемы
-
Кеширование данных: Gutenberg может кешировать определённые данные (включая слаг) для повышения производительности. После изменения слага через хук
save_post
отображаемое значение не обновляется немедленно. -
Отложенное обновление интерфейса: В процессе сохранения поста, если слаг меняется программно, Gutenberg не всегда получает уведомления о том, что изменения произошли. Это может быть связано с тем, что обновление слага происходит после выполнения основной логики сохранения поста, из-за чего редактор не видит новое значение без перезагрузки.
Рекомендации по решению проблемы
-
Использование
wp_update_post
после сохранения: Как вы уже делаете, измените слаг в функции обратного вызоваsave_post
. Однако после этого нужно также воспользоваться возможностью обновления данных в интерфейсе. -
Применение хуков для обновления состояния интерфейса: Рекомендуется использовать хук
edit_form_after_title
для вмешательства в вывод данных в редакторе. Вы можете написать JavaScript-код, который обновит интерфейс после публикации. -
AJAX для динамического обновления: Рассмотрите внедрение AJAX-вызовов для того, чтобы обновлять интерфейс без необходимости перезагрузки. Это позволит вам динамически обновлять значение слага в редакторе Gutenberg сразу после его изменения, без необходимости обновления страницы.
Пример кода
Вот пример реализации, как можно обновить интерфейс в Gutenberg после изменения слага:
add_action( 'admin_enqueue_scripts', 'custom_script_enqueue' );
function custom_script_enqueue() {
wp_enqueue_script( 'custom-gutenberg-slug', get_template_directory_uri() . '/js/gutenberg-slug.js', array('jquery'), null, true );
}
add_action( 'save_post', 'wpse105926_save_post_callback' );
function wpse105926_save_post_callback( $post_id ) {
// Ваша текущая логика для получения слага
// Обновление слага
wp_update_post(array(
'ID' => $post_id,
'post_name' => $slug,
));
// Добавьте последний параметр для отправки значения слага обратно в Gutenberg
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
wp_send_json_success(array('slug' => $slug));
}
}
// В файле js/gutenberg-slug.js
jQuery(document).ready(function($) {
$(document).on('post-save', function() {
// Запрос для обновления слага после публикации
$.post(ajaxurl, { action: 'get_updated_slug' }, function(response) {
if (response.success) {
// Обновляем отображаемый слаг в интерфейсе
$('#post_name').val(response.data.slug);
}
});
});
});
Заключение
Ваш код для обновления слага работает корректно на уровне базы данных, но для обеспечения мгновенного отображения необходимо обработать обновление интерфейса. Использование AJAX и кастомных JavaScript-функций позволит устранить необходимость перезагрузки страницы, что сделает работу в Gutenberg более гладкой и интуитивно понятной для конечного пользователя. Следуя предложенным рекомендациям, вы сможете улучшить функциональность вашего кастомного слага и исправить "косметическую" ошибку, с которой вы столкнулись.