Как отключить конкретные блоки Gutenberg в WordPress

Как отключить конкретные блоки Gutenberg в WordPress

WordPress предоставляет множество блоков по умолчанию, однако вам могут быть не нужны все из них. Чтобы избежать путаницы при создании и редактировании постов, вы можете отключить определённые блоки.

Для отключения блоков можно использовать разные способы: PHP, JavaScript или настройки пользователей. Выбор метода зависит от конкретной задачи. Например, использование JavaScript удобно, если вы уже применяете этот язык для других задач. В то же время, PHP предлагает решение на стороне сервера, которое легко добавить в существующие плагины и темы.

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

Содержание

  • Отключение блоков для текущего пользователя (настройки)
  • Отключение блоков с помощью PHP
  • Белый список (разрешённые блоки)
  • Использование условий
  • Использование параметра $block_editor_context
  • Чёрный список (запрещённые блоки)
  • Отключение блоков с помощью JavaScript
  • Отключение вариаций блоков
  • Атрибут allowedBlocks: белый список блоков внутри контейнерных блоков

Отключение блоков для текущего пользователя (настройки)

Вы можете скрыть конкретные блоки с помощью панели настроек редактора.

  1. Нажмите на значок настроек в верхнем правом углу экрана (три вертикальные точки).
  2. Выберите "Настройки".
  3. В открывшемся окне перейдите в раздел "Блоки".
  4. Отметьте те блоки, которые хотите скрыть (в списке зарегистрированных блоков).

Эти настройки сохраняются для пользователя, то есть блоки не удаляются, а просто скрываются для вашего пользоват��ля, оставаясь доступными для других.

Отключение блоков с помощью PHP

Для этого мы будем использовать хук allowed_block_types_all. У этого хука есть два параметра:

  • $allowed_block_types – массив с идентификаторами типовых блоков или булевое значение для активации/деактивации всех блоков.
  • $block_editor_context – текущее состояние блок-редактора.

Важно: если блок отключён через PHP, все шаблоны блоков, составленные из отключённых блоков, также станут недоступными для пользователя.

Важно! Для того чтобы блок был отключён с помощью PHP, он также должен быть зарегистрирован через PHP, а не через JS. Рекомендуется регистрировать блоки через файл block.json или функцию register_block_type().

Пример: Белый список (разрешённые блоки)

Простой пример, который позволяет пользователям вставлять только блоки Заголовок, Список, Изображение и Абзац.

Чтобы протестировать следующий код, добавьте его в файл functions.php вашей темы.

// Удалить все блоки, кроме указанных
add_filter( 'allowed_block_types_all', 'example_allowed_block_types', 10, 2 );

/**
 * @param array|bool $allowed_block_types Массив идентификаторов блоков или булевое для активации/деактивации всех.
 * @param object     $block_editor_context Текущий контекст блок-редактора.
 *
 * @return array Массовый массив разрешённых блоков.
 */
function example_allowed_block_types( $allowed_block_types, $block_editor_context ) {
    $allowed_block_types = array(
        'core/heading',     // Блок Заголовок
        'core/image',       // Блок Изображение
        'core/list',        // Блок Список
        'core/paragraph',   // Блок Абзац
    );

    return $allowed_block_types;
}

Использование условий

Давайте сделаем этот пример немного более реалистичным.

Если необходимо ограничить доступ авторов только к определённым блокам, но предоставить редакторам и администраторам доступ ко всем. Для этого можно использовать функцию current_user_can().

// Удалить все блоки, кроме указанных
add_filter( 'allowed_block_types_all', 'example_allowed_block_types', 10, 2 );

/**
 * @param array|bool $allowed_block_types Массив идентификаторов блоков или булевое для активации/деактивации всех.
 * @param object     $block_editor_context Текущий контекст блок-редактора.
 *
 * @return array Массовый массив разрешённых блоков.
 */
function example_allowed_block_types( $allowed_block_types, $block_editor_context ) {
    // Если текущий пользователь не имеет необходимых прав, ограничить блоки.
    if ( ! current_user_can( 'publish_pages' ) ) {
        $allowed_block_types = array(
            'core/heading',     // Блок Заголовок
            'core/image',       // Блок Изображение
            'core/list',        // Блок Список
            'core/paragraph',   // Блок Абзац
        );

        return $allowed_block_types;
    }

    // Разрешить все блоки
    return true;
}

Использование параметра $block_editor_context

Параметр $block_editor_context расширяет возможности условий, при которых блоки могут быть отключены. Например, можно определить тип редактируемого поста, выяснить, работает ли пользователь в редакторе или в редакторе сайта.

Посмотрим, как можно изменить код, чтобы ограничить блоки только при редактировании поста и разрешить все блоки, когда редактируется сайт. То есть мы оставим специфический список блоков только для постов типа post.

// Удалить все блоки, кроме указанных
add_filter( 'allowed_block_types_all', 'example_allowed_block_types', 10, 2 );

/**
 * @param array|bool $allowed_block_types Массив идентификаторов блоков или булевое для активации/деактивации всех.
 * @param object     $block_editor_context Текущий контекст блок-редактора.
 *
 * @return array Массовый массив разрешённых блоков.
 */
function example_allowed_block_types( $allowed_block_types, $block_editor_context ) {
    // Применяется только в редакторе при редактировании постов.
    if (
        'core/edit-post' === $block_editor_context->name
        && 'post' === ( $block_editor_context->post->post_type ?? '' )
    ) {
        $allowed_block_types = array(
            'core/heading',     // Блок Заголовок
            'core/image',       // Блок Изображение
            'core/list',        // Блок Список
            'core/paragraph',   // Блок Абзац
        );

        return $allowed_block_types;
    }

    // Разрешить все блоки
    return true;
}

Возможные значения $block_editor_context->name:

  • core/edit-post – Редактор постов
  • core/edit-site – Редактор сайта
  • core/widgets – Редактор виджетов
  • core/customize-widgets – Редактор виджетов в пользовательском интерфейсе

Чёрный список (запрещённые блоки)

Выше мы рассмотрели разрешённые блоки. Однако, если у вас сотни блоков, удобнее указать только те, которые нужно запретить.

Мы можем создать массив с ненужными блоками, затем программно получить весь список существующих блоков и исключить из него указанные.

Для получения полного списка блоков используем метод WP_Block_Type_Registry::get_all_registered().

Рассмотрим пример отключения блоков Навигация и Запрос для пользователей без прав edit_theme_options (обычно это привилегия администратора).

add_filter( 'allowed_block_types_all', 'wpkama_disable_gutenberg_blocks', 30, 2 );
function wpkama_disable_gutenberg_blocks( $allowed_blocks, $block_editor_context ) {
    $disable_blocks = [
        'core/calendar',
        'core/comment-author-name',
        'core/comment-content',
        'core/comment-date',
        'core/comment-edit-link',
        'core/comment-reply-link',
        'core/comment-template',
        'core/comments',
        'core/comments-pagination',
        'core/comments-pagination-next',
        'core/comments-pagination-numbers',
        'core/comments-pagination-previous',
        'core/comments-title',
        'core/embed',
    ];

    // Получаем все зарегистрированные блоки, если $allowed_block_types ещё не задан.
    if( ! is_array( $allowed_blocks ) || empty( $allowed_blocks ) ){
        $registered_blocks = WP_Block_Type_Registry::get_instance()->get_all_registered();
        $allowed_blocks = array_keys( $registered_blocks );
    }

    foreach( $allowed_blocks as $index => $block_id ){
        if( in_array( $block_id, $disable_blocks, true ) ){
            unset( $allowed_blocks[ $index ] );
        }
    }

    return array_values( $allowed_blocks ); // возращаем массив
}

Отключение блоков с помощью JavaScript

Реализация ограничения блоков с помощью JavaScript требует создания и подключения JavaScript файла в редакторе.

Для следующего примера код скрипта будет находиться в файле темы (путь к скрипту будет указан относительно темы).

  1. Создайте файл restrict-blocks.js (название произвольное) и поместите его в папку assets/js вашей темы.
  2. Подключите этот файл, используя хук enqueue_block_editor_assets и стандартную функцию wp_enqueue_script().
add_action( 'enqueue_block_editor_assets', 'example_enqueue_block_restrictions' );
function example_enqueue_block_restrictions() {
    wp_enqueue_script(
        'example-enqueue-block-variations',
        get_template_directory_uri() . '/assets/js/restrict-blocks.js',
        array( 'wp-blocks', 'wp-dom-ready' ),
        wp_get_theme()->get( 'Version' ),
        false
    );
}

Обратите внимание, что зависимости wp-blocks и wp-dom-ready необходимы для установления ограничений в примерах ниже.

Пример: Белый список (разрешённые блоки) в JavaScript

Здесь логика отличается от PHP-версии.

Чтобы оставить лишь несколько блоков, сначала нужно получить список всех существующих блоков, используя wp.blocks.getBlockTypes(). Затем переберите список и отключите все блоки, которые не указаны в белом списке.

Блоки отменяются с помощью метода wp.blocks.unregisterBlockType(), который принимает имя блока. Этот метод требует зависимости wp-blocks (упомянутая при регистрации скрипта).

wp.domReady( () => {
    // Разрешить только блоки Заголовок, Изображение, Список и Абзац
    const allowedBlocks = [
        'core/heading',
        'core/image',
        'core/list',
        'core/paragraph',
    ];

    wp.blocks.getBlockTypes().forEach( blockType =>  {
        if ( allowedBlocks.indexOf( blockType.name ) === -1 ) {
            wp.blocks.unregisterBlockType( blockType.name );
        }
    } );
} );

Важно использовать wp.domReady при отмене регистрации блоков. В противном случае функция может сработать слишком рано и не удалит блок.

Использование ��словий в JavaScript

Так же, как и в PHP-методах, можно добавить условия. Например, метод canUser() из пакета @wordpress/data-core позволяет получить права пользователя, а пакет @wordpress/data-core-editor предоставляет удобный метод getCurrentPostType().

Эти методы позволяют определить текущий тип поста и проверить, может ли пользователь обновлять настройки.

wp.domReady( () => {
    const { canUser } = wp.data.select( 'core' );
    const { getCurrentPostType } = wp.data.select( 'core/editor' );

    // Проверяем права пользователя и получаем текущий тип поста.
    const canUserUpdateSettings = canUser( 'update', 'settings' );
    const currentPostType = getCurrentPostType();

    const allowedBlocks = [
        'core/heading',
        'core/image',
        'core/list',
        'core/paragraph',
    ];

    if ( ! canUserUpdateSettings && currentPostType === 'post' ) {
        wp.blocks.getBlockTypes().forEach( blockType => {
            if ( allowedBlocks.indexOf( blockType.name ) === -1 ) {
                wp.blocks.unregisterBlockType( blockType.name );
            }
        } );
    }
} );

Чёрный список (запрещённые блоки) в JavaScript

Когда необходимо отключить только несколько блоков, более удобным будет использование следующего кода. Например, если нам нужно удалить два блока core/navigation и core/query, нет необходимости получать список всех блоков; довольно просто отключить ненужные.

wp.domReady( () => {
    wp.blocks.unregisterBlockType( 'core/navigation' );
    wp.blocks.unregisterBlockType( 'core/query' );
} );

Если необходимы условия, так же, как в предыдущем примере, используйте методы из пакетов core и core/editor.

wp.domReady( () => {
    const { canUser } = wp.data.select( 'core' );
    const { getCurrentPostType } = wp.data.select( 'core/editor' );

    if ( ! canUser( 'update', 'settings' ) && getCurrentPostType() === 'post' ) {
        wp.blocks.unregisterBlockType( 'core/navigation' );
        wp.blocks.unregisterBlockType( 'core/query' );
    }
} );

JavaScript-метод, вероятно, предпочтительнее, поскольку регистрация блоков выполняется в JavaScript, и таким образом у нас больше возможностей. Например, если блок зарегистрирован через JS, он просто не будет виден в PHP, тогда как в JS он будет существовать.

Отключение вариаций блоков

Вариации блоков часто могут быть ошибочно приняты за отдельные блоки, но это не так.

Проще говоря, вариации блоков — это один блок, который имеет разные опции, и каждая из этих опций отображается в редакторе в виде отдельного блока.

Например, блоки встраивания:

Встраиваемые блоки

Все эти блоки являются одним блоком core/embed, и если мы отключим этот блок, то мы отключим все вариации этого блока. Поэтому их нельзя отключать с помощью методов, описанных ранее. Тем не менее, иногда необходимо отключить конкретную вариацию, оставив другие вариации.

Другим примером вариации будет группировка (group):

Вариации групп

Рассмотрим пример отключения вариаций группы Row, Stack и встраивания вариации YouTube.

wp.domReady( () => {
    wp.blocks.unregisterBlockVariation( 'core/group', 'group-row' );
    wp.blocks.unregisterBlockVariation( 'core/group', 'group-stack' );
    wp.blocks.unregisterBlockVariation( 'core/embed', 'youtube' );
} );

Атрибут allowedBlocks: белый список блоков внутри контейнерных блоков

Некоторые блоки могут содержать другие блоки. Давайте назовём такие блоки контейнерными. Примером такого контейнерного блока является блок "Группа". Иногда может потребоваться ограничить список блоков, которые можно использовать внутри контейнерного блока.

Для WordPress 6.4 атрибут allowedBlocks поддерживает четыре блока:

  • Колонка
  • Обложка
  • Медиа и текст
  • Группа (включает вариации):
    • Строка
    • Стек
    • Сетка

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

Например, если вы хотите разрешить только блоки "Заголовок" и "Абзац" внутри определённого контейнерного блока, следует использовать следующую настройку блока:

{"allowedBlocks":["core/heading","core/paragraph"]}

Важно отметить, что так как это ограничение контролируется атрибутом, пользователи теоретически могут переключиться в Редактор кода, удалить атрибут и добавить любые блоки, которые им нужны. Если необходимо запретить такую возможность, вы можете ограничить доступ к Редактору кода с помощью PHP.

Отключение доступа к редактору кода

Редактор кода позволяет просматривать базовую разметку блока для страницы или поста. Это может быть полезно, но только если вы опытный пользователь; в противном случае вы можете случайно повредить разметку блока, редактируя содержимое. Чтобы ограничить доступ пользователей к редактированию HTML-кода, добавьте следующий код в functions.php вашей темы.

add_filter( 'block_editor_settings_all', 'example_restrict_code_editor_access', 10, 2 );
function example_restrict_code_editor_access( $settings, $context ) {
    $settings[ 'codeEditingEnabled' ] = false;

    return $settings;
}

Этот код предотвращает доступ к редактору кода ��ля всех пользователей.

Теперь вы знаете, как отключить ненужные блоки в редакторе Gutenberg, используя различные методы и подходы. Это позволяет сделать процесс редактирования более удобным и организованным как для вас, так и для ваших пользователей.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *