Отключить интерактивность для основной навигации

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

Я хочу отключить стандартное поведение интерактивности в блоке навигации. Я попробовал сделать следующее:

Загрузить свою вариацию блока в functions.php:

function da_custom_block_variations() {
    wp_enqueue_script(
        'da-custom-navigation-block',
        get_stylesheet_directory_uri() . '/assets/js/navigation/block.js',
        array( 'wp-blocks' ),
        null,
        true
    );
}
add_action( 'enqueue_block_editor_assets', 'da_custom_block_variations' );

Зарегистрировать свою вариацию в block.js:

wp.blocks.registerBlockVariation(
    'core/navigation',
    {
        name: 'da-navigation',
        title: 'DA Navigation без поддержки интерактивности',
        description: 'Навигация без поддержки интерактивности',
        isDefault: true,
        supports: {
            interactivity: false,
        },
    }
);

Я могу использовать свою вариацию блока, но когда я выбираю открытие подменю по клику, поведение клика все равно применяется. После чтения о API вариаций, кажется, я не могу отключить интерактивность. https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/

Как я могу отключить стандартную интерактивность навигации (aria-expands=true/false) и добавить свою?

После множества чтений, отладки и тестирования мне не удалось модифицировать стандартный блок core/navigation так, как я хотел. API интерактивности по-прежнему мешает. Таким образом, моим решением было включить классическое меню и сделать его пользовательским динамическим блоком:

Файл functions.php моей темы:

function my_theme_register_menus()
{
    register_nav_menus(
        array(
            'primary' => __('Основное меню', 'my-theme'),
        )
    );
}
add_action('after_setup_theme', 'my_theme_register_menus');

Файл render.php моего блока навигации темы:

<?php

$walker = new Classic_Nav_Walker();

$menu_location = isset( $attributes['menuLocation'] ) ? $attributes['menuLocation'] : 'primary';

wp_nav_menu(
    array(
        'theme_location'  => $menu_location,
        'walker'          => $walker,
        'container'       => 'nav',
        'container_class' => 'my-theme-navigation',
        'echo'            => true,
    )
);

Edit.js:

import { __ } from "@wordpress/i18n";
import { useBlockProps } from "@wordpress/block-editor";
import ServerSideRender from "@wordpress/server-side-render";
import "./editor.scss";
export default function Edit() {
    return (
        <div { ...useBlockProps() }>
            <ServerSideRender block="my-theme/my-theme-navigation" />
        </div>
    );
}

И немного пользовательского поведения внутри view.js. Недостаток в том, что вы не можете изменять навигацию внутри редактора полного сайта.

Надеюсь, это поможет, если кто-то ищет похожее решение.

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

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

Шаг 1: Регистрация меню в functions.php

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

function my_theme_register_menus() {
    register_nav_menus(
        array(
            'primary' => __('Primary Menu', 'my-theme'),
        )
    );
}
add_action('after_setup_theme', 'my_theme_register_menus');

Шаг 2: Создание класса для Walker

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

class Classic_Nav_Walker extends Walker_Nav_Menu {
    // Переопределите необходимые методы, чтобы настроить вывод меню
    // Например:
    function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
        // Здесь вы можете настроить, как будет выводиться каждый элемент меню
        $output .= '<li>' . esc_html($item->title) . '</li>';
    }
}

Шаг 3: Рендеринг блока навигации

В вашем файле render.php нужно использовать функцию wp_nav_menu() с параметрами, которые передадут меню в соответствии с вашим классом Walker:

function render_my_theme_navigation($attributes) {
    $walker = new Classic_Nav_Walker();
    $menu_location = isset($attributes['menuLocation']) ? $attributes['menuLocation'] : 'primary';

    wp_nav_menu(
        array(
            'theme_location' => $menu_location,
            'walker'         => $walker,
            'container'      => 'nav',
            'container_class' => 'my-theme-navigation',
            'echo'           => true,
        )
    );
}

Шаг 4: Создание виджета блока в edit.js

Затем создайте блок для редактирования, который будет использовать серверный рендеринг:

import { __ } from "@wordpress/i18n";
import { useBlockProps } from "@wordpress/block-editor";
import ServerSideRender from "@wordpress/server-side-render";
import "./editor.scss";

export default function Edit() {
    return (
        <div { ...useBlockProps() }>
            <ServerSideRender block="my-theme/my-theme-navigation" />
        </div>
    );
}

Шаг 5: Обработчик видимости в view.js

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

document.querySelectorAll('.my-theme-navigation li').forEach(item => {
    item.addEventListener('click', function() {
        // Ваша кастомная логика для обработки кликов
    });
});

Итог

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

Если у вас возникнут дополнительные вопросы или понадобится помощь, не стесняйтесь обращаться!

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

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