Почему мой пользовательский слуг отображается в редакторе Gutenberg только после обновления страницы?

Вопрос или проблема

Я использую поле 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 до тех пор, пока вы не обновите страницу. Давайте рассмотрим, почему это происходит и как можно улучшить поведение вашего кода.

Причины проблемы

  1. Кеширование данных: Gutenberg может кешировать определённые данные (включая слаг) для повышения производительности. После изменения слага через хук save_post отображаемое значение не обновляется немедленно.

  2. Отложенное обновление интерфейса: В процессе сохранения поста, если слаг меняется программно, Gutenberg не всегда получает уведомления о том, что изменения произошли. Это может быть связано с тем, что обновление слага происходит после выполнения основной логики сохранения поста, из-за чего редактор не видит новое значение без перезагрузки.

Рекомендации по решению проблемы

  1. Использование wp_update_post после сохранения: Как вы уже делаете, измените слаг в функции обратного вызова save_post. Однако после этого нужно также воспользоваться возможностью обновления данных в интерфейсе.

  2. Применение хуков для обновления состояния интерфейса: Рекомендуется использовать хук edit_form_after_title для вмешательства в вывод данных в редакторе. Вы можете написать JavaScript-код, который обновит интерфейс после публикации.

  3. 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 более гладкой и интуитивно понятной для конечного пользователя. Следуя предложенным рекомендациям, вы сможете улучшить функциональность вашего кастомного слага и исправить "косметическую" ошибку, с которой вы столкнулись.

Оцените материал
Добавить комментарий

Капча загружается...