По правилам юзабилити, ничего не должно содержать ссылку на себя. Если пользователь переходит на страницу, например, «Контакты», пункт меню «Контакты» должен потерять интерактивность, это правильное и хорошее поведение. Как это сделать в wordpress? При помощи правки functions.php
Для начала, поместите в functions.php следующий код:
/**
* Extension for wp_nav_menu()
* Remove element "a" from current menu item
*
* Optional $args contents additional arguments
* string replace_a_by - Whether to wrap the link text node, and what to wrap it with. Default 'span'.
* string xpath - xPath expression.
*
* @param $args
* @see wp_nav_menu()
* @return mixed Menu output if $echo is false, false if there are no items or no menu was found.
*/
function wp_nav_menu_extended($args = array()) {
$_echo = array_key_exists('echo', $args) ? $args['echo'] : true;
$args['echo'] = false;
$menu = wp_nav_menu($args);
// Load menu as xml
$menu = simplexml_load_string($menu);
// Find current menu item with xpath selector
if (array_key_exists('xpath', $args)) {
$xpath = $args['xpath'];
} else {
$xpath = '//li[contains(@class, "current-menu-item") or contains(@class, "current_page_item")]';
}
$current = $menu->xpath($xpath);
// If current item exists
if (!empty($current)) {
$text_node = (string) $current[0]->children();
// Remove link
unset($current[0]->a);
// Create required element with text from link
$element_name = $args['replace_a_by'] ? $args['replace_a_by'] : 'span';
$dom = dom_import_simplexml($current[0]);
$n = $dom->insertBefore(
$dom->ownerDocument->createElement($element_name, $text_node),
$dom->firstChild
);
$current[0] = simplexml_import_dom($n);
}
$xml_doc = new DOMDocument('1.0', 'utf-8');
$menu_x = $xml_doc->importNode(dom_import_simplexml($menu), true);
$xml_doc->appendChild($menu_x);
$menu = $xml_doc->saveXML($xml_doc->documentElement);
if ($_echo) {
echo $menu;
} else {
return $menu;
}
}
А затем разместите в header.php вот такой вызов:
<?php wp_nav_menu_extended( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu') ); ?>
Остаётся понять, как проделать эту же операцию с заголовком блога. Лечится заменой вызова заголовка в header.php вот таким образом:
<h1 class="vcard author">
<?php if ( is_front_page() && !is_paged())
echo bloginfo('name');
else echo "";
?>
</h1>
<h1 class="vcard author">
<a href="<?php echo get_option('home'); ?>/" title="На главную страницу">
<?php if ( is_front_page() && !is_paged())
echo "";
else
echo bloginfo('name');
?>
</a>
</h1>
UPD: 15 апреля 2024 года. Способ устарел и на блочных темах уже не работает. Теперь надо править CSS. Вносим в дополнительный CSS следующую конструкцию:
.wp-block-navigation .current-menu-item [aria-current="page"] {
pointer-events: none;
cursor: default;
}
Посмотрите только, каким классом оформлено ваше меню и поместите его в первой строке вместо .wp-block-navigation и всё сработает.
Вы, конечно, спросите, а как быть с заголовком блога? Как сделать, чтобы когда пользователь находится на главной странице, заголовок не был интерактивным, а когда на дочерних — был? Вот так:
.wp-block-site-title [aria-current="page"] {
pointer-events: none;
cursor: default;
}