Вопрос или проблема
Я хочу отключить стандартное поведение интерактивности в блоке навигации. Я попробовал сделать следующее:
Загрузить свою вариацию блока в 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, вы создали свой собственный динамический блок навигации, который может быть адаптирован под ваши требования. Конечно, у этого подхода есть свои недостатки, например, вы не сможете редактировать меню через редактор сайта. Однако, если вам нужна полная степень контроля над выводом навигации и отсутствием интерактивности, это будет эффективное решение.
Если у вас возникнут дополнительные вопросы или понадобится помощь, не стесняйтесь обращаться!