Проблема с пользовательским блоком Gutenberg – этот блок столкнулся с ошибкой и не может быть предварительно просмотрен.

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

У меня проблема с моим пользовательским блоком Gutenberg. Сам по себе он работает идеально на каждой странице или посте. Но, когда я хочу добавить этот блок, который настроен как динамический, к пользовательскому типу записи, появляется сообщение “Этот блок столкнулся с ошибкой и не может быть предпросмотрен.”. В чем может быть проблема? Код приведен здесь. Заранее спасибо.

plugin.php – определение пользовательского блока Gutenberg

function movieFavQuote() {
  wp_enqueue_script(
    'favquote-handler',
    plugin_dir_url(__FILE__) . 'quote-block.js',
    array('wp-blocks', 'wp-i18n', 'wp-editor'),
    true
  );
}
 
add_action('enqueue_block_editor_assets', 'movieFavQuote');

function favQuoteMeta() {
  register_meta('post', 'content', array('show_in_rest' => true, 'type' => 'string', 'single' => true));
}

add_action('init', 'favQuoteMeta');

quote-block.js – определение пользовательского блока Gutenberg

wp.blocks.registerBlockType('pavle/movie-quote', {
    title: 'Любимая цитата из фильма',
    icon: "smiley",
    category: "common",
    attributes: {
        content: {type: 'string', source: 'meta', meta: 'content'}
    },

    edit: function(props) {
        function updateContent(event) {
        props.setAttributes({content: event.target.value})
        }

        return wp.element.createElement(
            "div",
            null,
            wp.element.createElement("h3", null, " Любимая цитата из фильма: "),
            wp.element.createElement("input", {
              type: "text",
              value: props.attributes.content,
              onChange: updateContent
            })
          );
    },
    save: function(props) {
        return wp.element.createElement("h2", null, " Любимая цитата из фильма:", props.attributes.content);
    }
})

movies.php – определение пользовательского типа записи

<?php

    function movie_cpt() {
    
            $labels = array(
    'name'                  => _x( 'Фильмы', 'Post Type General Name', 'text_domain' ),
    'singular_name'         => _x( 'Фильм', 'Post Type Singular Name', 'text_domain' ),
    'menu_name'             => __( 'Фильмы', 'text_domain' ),
    'name_admin_bar'        => __( 'Фильмы', 'text_domain' ),
    'archives'              => __( 'Архив фильмов', 'text_domain' ),
    'attributes'            => __( 'Атрибуты элемента', 'text_domain' ),
    'parent_item_colon'     => __( 'Родительский элемент:', 'text_domain' ),
    'all_items'             => __( 'Все фильмы', 'text_domain' ),
    'add_new_item'          => __( 'Добавить новый фильм', 'text_domain' ),
    'add_new'               => __( 'Добавить новый фильм', 'text_domain' ),
    'new_item'              => __( 'Новый фильм', 'text_domain' ),
    'edit_item'             => __( 'Редактировать фильм', 'text_domain' ),
    'update_item'           => __( 'Обновить фильм', 'text_domain' ),
    'view_item'             => __( 'Просмотреть фильм', 'text_domain' ),
    'view_items'            => __( 'Просмотреть фильм', 'text_domain' ),
    'search_items'          => __( 'Поиск фильмов', 'text_domain' ),
    'not_found'             => __( 'Фильм не найден', 'text_domain' ),
    'not_found_in_trash'    => __( 'Фильм не найден в корзине', 'text_domain' ),
    'featured_image'        => __( 'Изображение записи', 'text_domain' ),
    'set_featured_image'    => __( 'Установить изображение записи', 'text_domain' ),
    'remove_featured_image' => __( 'Удалить изображение записи', 'text_domain' ),
    'use_featured_image'    => __( 'Использовать как изображение записи', 'text_domain' ),
    'insert_into_item'      => __( 'Вставить в элемент', 'text_domain' ),
    'uploaded_to_this_item' => __( 'Загружено в этот элемент', 'text_domain' ),
    'items_list'            => __( 'Список фильмов', 'text_domain' ),
    'items_list_navigation' => __( 'Навигация по списку элементов', 'text_domain' ),
    'filter_items_list'     => __( 'Фильтр списка элементов', 'text_domain' ),
);
$args = array(
    'label'                 => __( 'Фильм', 'text_domain' ),
    'description'           => __( 'Описание типа записи', 'text_domain' ),
    'labels'                => $labels,
    'supports'              => array( 'title', 'editor'),
    'taxonomies'            => array( 'category', 'post_tag' ),
    'hierarchical'          => false,
    'public'                => true,
    'show_ui'               => true,
    'show_in_menu'          => true,
    'menu_position'         => 5,
    'show_in_admin_bar'     => true,
    'show_in_nav_menus'     => true,
    'can_export'            => true,
    'has_archive'           => true,
    'exclude_from_search'   => false,
    'publicly_queryable'    => true,
    'capability_type'       => 'page',
    'show_in_rest'          => true,
    'register_meta_box_cb'  => 'movie_meta_box'
);
        register_post_type( 'movie', $args );
    
    }
    add_action( 'init', 'movie_cpt');
        
    function movie_meta_box() {
            add_meta_box(
                'movie-title',
                __('Название фильма', 'sitepoint'),
                'movie_title_meta_box_callback',
            );
    }
    
    add_action('add_meta_boxes_movie', 'movie_meta_box');
    
    function movie_title_meta_box_callback($post) {
        wp_nonce_field('movie_title_nonce', 'movie_title_nonce');
        $value = get_post_meta($post->ID, '_movie_title', true);
        echo '<textarea style = "width:100%" id="movie_title" name="movie_title">' . esc_attr( $value ) . '</textarea>';
    }
    function save_movie_title_meta_box_data($post_id) {
        if (!isset($_POST['movie_title_nonce'])) {
            return;
        }
        if(!wp_verify_nonce( $_POST['movie_title_nonce'], 'movie_title_nonce' )) {
            return;
        }
        if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }
        if(isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
            if ( ! current_user_can( 'edit_page', $post_id ) ) {
                return;
            }
        }
        else {
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                return;
            }
        }
        if(!isset($_POST['movie_title'])) { 
            return; 
        }
        $my_data = sanitize_text_field( $_POST['movie_title'] );
        update_post_meta( $post_id, '_movie_title', $my_data );
    }
    
    add_action('save_post', 'save_movie_title_meta_box_data');

Попробуйте добавить custom-fields в массив поддержки;

'supports'  => [
        'title',
        'editor',
        'thumbnail',
        'custom-fields'
    ],

Ответ или решение

Ошибка с блоком Gutenberg, о которой идет речь, чаще всего связана с тем, что блок или не может получить нужные данные из мета-полей, или просто неправильно зарегистрирован для работы с определённым типом контента. Давайте проанализируем несколько возможных причин этого и предложим решения.

Теория

Одной из основных причин проблемы может быть несоответствие в настройках регистрации мета-полей и способов их возращения в REST API. В вашем коде используется функция register_meta для определения мета-поля ‘content’. Однако, если этот мета-подключенный блок должен работать с конкретным типом записи, то нужно убедиться, что:

  1. Мета-поля зарегистрированы корректно и связаны с нужным типом записи.
  2. Блок зарегистрирован в конфигурации REST API.

Пример

Отрывок вашего кода, регистрирующий мета-полe, выглядит следующим образом:

register_meta('post', 'content', array('show_in_rest' => true, 'type' => 'string', 'single' => true));

В этой строке функция связывает мета-поле ‘content’ с типом постов ‘post’. Но учитывая, что ваш блок используется в кастомном пост-типе ‘movie’, это создает конфликт. Вы дополнительно можете добавить проверку на наличие этого мета-поля для вашего кастомного типа записи.

Также, в movies.php у вас не добавлены ‘custom-fields’ в параметр ‘supports’. При добавлении, ваш код может менять настройки и доступа к мета-полям, связанным с пост типом.

Применение

  1. Обновите регистрацию мета-полей, чтобы она была более специфичной для вашего кастомного пост-типа:

    function favQuoteMeta() {
       register_meta('movie', 'content', array('show_in_rest' => true, 'type' => 'string', 'single' => true))
    }
    add_action('init', 'favQuoteMeta');
  2. Убедитесь, что в конфигурации кастомного пост-типа включено ‘supports’ для поддержки ‘custom-fields’:

    $args = array(
       'supports' => array('title', 'editor', 'thumbnail', 'custom-fields')
       // Остальные параметры
    );

Эти изменения должны обеспечить корректную работу вашего динамического блока в рамках настроенного типа постов. За счет этого ошибки в отображении блока Gutenberg при использовании в кастомных записях ‘movie’ быть не должно. Будьте внимательны к изменению структуры доступа ваших данных и их синхронизации с REST API.

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

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