11 хаков для Админ-бара WordPress (тулбара)
C версии 3.1 в WordPress появился «Админ бар» (admin bar), задача которого была предоставить быстрый доступ к страницам админ-панели. А с версии 3.3 он немного изменил свое назначение и стал называться «Панель инструментов» (toolbar или тулбокс). Внешне и в коде ничего не поменялось, изменился подход: теперь он стал полностью поддерживать внешнюю часть сайта (фронт-энд). А когда не было этой панели инструментов мне её очень не хватало и я даже написал один из первых плагинов.
В этой заметке я соберу разные приёмы, для изменения этой панели инструментов (тулбара, админ бара): добавление, изменение, удаление элементов и т.д.
Для создания панели инструментов в WordPress есть отдельный класс WP_Admin_Bar и ряд функций. По сути, работа всей панель описана в этих двух файлах. И если вы чего-то не найдете в этой статье, то можете попробовать разобраться там.
Для вставки кодов можно воспользоваться неплохим плагином: Code Snippets
Еще примеры смотрите в описании WP_Admin_Bar.
Удобное скрытие панели инструментов
Build In PostМне не нравится как панель расположена вверху во фронт-энде. Она часто не гармонирует с дизайном, но это можно пережить. Но когда она начинает мешать при всяких прокрутках или дополнительных плавающих панелях, то тут уже определенно надо что-то делать.
На мой взгляд самое универсальное решение — сделать эту панель скрывающейся (сворачивающейся). Так она не будет мешать и когда нужно под рукой.
По этому вопросу я искал плагины, но нашел каких-то монстров. Поэтому пришлось написать свой код. То что получилось мне нравится, в некоторых случаях это очень удобно: кроме того что панель не мешает, она еще и способна вместить больше элементов. Суть заключается в том, что панель появляется при наведении на иконку в верхнем левом углу и появляется она в вертикальном виде, а не горизонтальном. Получается своего рода сворачивание админ бара.
Вот так это выглядит на теме Twenty Twenty-One:
Код, который делает такие преобразования:
<?php /** * Сollapse ADMIN-BAR (Toolbar) into left-top corner. * * @version 1.0 */ final class Kama_Collapse_Toolbar { public static function init(){ add_action( 'admin_bar_init', [ __CLASS__, 'hooks' ] ); } public static function hooks(){ // remove html margin bumps remove_action( 'wp_head', '_admin_bar_bump_cb' ); add_action( 'wp_head', [ __CLASS__, 'collapse_styles' ] ); } public static function collapse_styles(){ // do nothing for admin-panel. // Remove this if you want to collapse admin-bar in admin-panel too. if( is_admin() ){ return; } ob_start(); ?> <style id="kama_collapse_admin_bar"> #wpadminbar{ background:none; float:left; width:auto; height:auto; bottom:0; min-width:0 !important; } #wpadminbar > *{ float:left !important; clear:both !important; } #wpadminbar .ab-top-menu li{ float:none !important; } #wpadminbar .ab-top-secondary{ float: none !important; } #wpadminbar .ab-top-menu>.menupop>.ab-sub-wrapper{ top:0; left:100%; white-space:nowrap; } #wpadminbar .quicklinks>ul>li>a{ padding-right:17px; } #wpadminbar .ab-top-secondary .menupop .ab-sub-wrapper{ left:100%; right:auto; } html{ margin-top:0!important; } #wpadminbar{ overflow:hidden; width:33px; height:30px; } #wpadminbar:hover{ overflow:visible; width:auto; height:auto; background:rgba(102,102,102,.7); } /* the color of the main icon */ #wp-admin-bar-<?= is_multisite() ? 'my-sites' : 'site-name' ?> .ab-item:before{ color:#797c7d; } /* hide wp-logo */ #wp-admin-bar-wp-logo{ display:none; } /* #wp-admin-bar-search{ display:none; } */ /* edit for twentysixteen */ body.admin-bar:before{ display:none; } /* for almin panel --- */ @media screen and ( min-width: 782px ) { html.wp-toolbar{ padding-top:0 !important; } #wpadminbar:hover{ background:rgba(102,102,102,1); } #adminmenu{ margin-top:48px !important; } } /* Gutenberg */ #wpwrap .edit-post-header{ top:0; } #wpwrap .edit-post-sidebar{ top:56px; } </style> <?php $styles = ob_get_clean(); echo preg_replace( '/[\n\t]/', '', $styles ) ."\n"; } }
Теперь нужно скопировать этот код в файл, подключить этот файл в functions.php и запустить класс так:
Kama_Collapse_Toolbar::init();
Ещё один вариант простой реализации:
<?php final class Jackky_Collapse_Admin_Bar { public static function init() { add_action( 'admin_bar_init', [ __CLASS__, 'hooks' ] ); } public static function hooks() { // remove html margin bumps remove_action( 'wp_head', '_admin_bar_bump_cb' ); add_action( 'wp_enqueue_scripts', [ __CLASS__, 'collapse_styles' ] ); add_action( 'admin_bar_menu', [ __CLASS__, 'remove_nodes' ], 999 ); } public static function collapse_styles() { $styles = " #wpadminbar { transition: clip-path .3s ease 1s, background-color .2s ease 1s; clip-path: polygon( 0 0, 32px 0, 32px 100%, 0 100% ); } #wpadminbar:not( :hover ) { background-color: rgba( 29, 35, 39, 0 ); } #wpadminbar:not( :hover ) .ab-item::before { color: #1d2327; transition-delay: 1s; } #wpadminbar .ab-item { position: relative; } #wpadminbar #wp-admin-bar-site-name > .ab-item::after { content: ''; position: absolute; top: 7px; left: 7px; z-index: -1; width: 20px; height: 20px; border-radius: 50%; background-color: #fff; opacity: .8; transition: opacity .2s ease 1s; } #wpadminbar:hover #wp-admin-bar-site-name > .ab-item::after { opacity: 0; transition-delay: 0s; } #wpadminbar:not( :hover ) > * { pointer-events: none; } #wpadminbar:hover { transition-delay: 0s; clip-path: polygon( 0 0, 100% 0, 100% 100vh, 0 100vh ); } @media screen and ( max-width: 782px ) { #wpadminbar { clip-path: polygon( 0 0, 50px 0, 50px 100%, 0 100% ); } } "; wp_register_style( 'collapse-admin-bar', false ); wp_add_inline_style( 'collapse-admin-bar', $styles ); wp_enqueue_style( 'collapse-admin-bar' ); } public static function remove_nodes( $wp_admin_bar ) { $wp_admin_bar->remove_node( 'wp-logo' ); $wp_admin_bar->remove_node( 'search' ); } } add_action( 'init', [ Jackky_Collapse_Admin_Bar::class, 'init' ] );
Вставлять этот код нужно в functions.php или оформите из него плагин, если часто меняете шаблоны.
Для работы кода, нужно чтобы в footer.php темы вызывалась функция wp_footer().
Удаление базовых элементов (ссылок) из тулбара
Build In PostВидел в сети решение этой задачи - везде немного не правильно, потому что пункты удаляются после того как они были добавлены в панель. А желательно их вообще туда не добавлять. Делается это так:
## Удаление базовых элементов (ссылок) из тулбара add_action( 'add_admin_bar_menus', function(){ /* доступно для удаления: remove_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 0 ); // Внутренние ссылки меню профиля remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 ); // поиск remove_action( 'admin_bar_menu', 'wp_admin_bar_my_account_item', 7 ); // Полностью меню профиля // Связанное с сайтом remove_action( 'admin_bar_menu', 'wp_admin_bar_sidebar_toggle', 0 ); // remove_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 ); // WordPress ссылки (WordPress лого) remove_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 ); // мои сайты remove_action( 'admin_bar_menu', 'wp_admin_bar_site_menu', 30 ); // сайты remove_action( 'admin_bar_menu', 'wp_admin_bar_customize_menu', 40 ); // настроить тему remove_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 50 ); // обновления // Content related. if ( ! is_network_admin() && ! is_user_admin() ) { // комментарии remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 ); // добавить запись, страницу, медиафайл и т.д. remove_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 70 ); } // редактировать remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 ); // вся дополнительная группа (поиск и аккаунт) расположена справа в меню remove_action( 'admin_bar_menu', 'wp_admin_bar_add_secondary_groups', 200 ); */ // удаляем remove_action( 'admin_bar_menu', 'wp_admin_bar_customize_menu', 40); // Настроить тему remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 ); // поиск remove_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 ); // WordPress ссылки (WordPress лого) });
В закомментированных строках указанны те пункты панели, которые можно удалить. В этом примере удалены пункты: «Настроить», «Поиск» и основной пункт с WordPress ссылками.
Удаление/отключение панели инструментов (тулбара)
Build In PostВо-первых тулбар можно отключить на странице профиля а админ-панели: Пользователи > Ваш профиль
.
Но когда нужно отключить глобально, используйте функцию show_admin_bar().
Смотрите также:
- show_admin_bar - хук.
- show_admin_bar() - функция.
Примеры разных вариантов отключения:
Мягкое отключение
Предположим, нам нужно отключить "Панель инструментов" в лицевой части сайта. Но при этом, нужно дать возможность плагинам, включить панель через фильтр show_admin_bar.
Для этого вставьте следующую строку в файл темы functions.php:
show_admin_bar( false );
Полностью отключаем панель
На фронте и в админке:
// Отключаем админ бар во фронте add_filter( 'show_admin_bar', '__return_false' ); // Отключаем админ бар в админ панели remove_action( 'in_admin_header', 'wp_admin_bar_render', 0 );
Отключаем тулбар для всех кроме администратора (во фронте)
В этом примере панель инструментов не отключается в админ-панели.
add_filter( 'show_admin_bar', 'admin_bar_for_admin_only', 99 ); function admin_bar_for_admin_only( $show_admin_bar ) { if ( $show_admin_bar && ! current_user_can( 'manage_options' ) ) { $show_admin_bar = false; } return $show_admin_bar; }
По аналогии можно отключить панель для любой роли. Для этого вместо права 'manage_options'
нужно указать подходящее право для роли, список прав смотрите здесь. Вот некоторые из них:
publish_posts
- авторedit_others_posts
- редактор
Отключаем тулбар для администратора сети
add_filter( 'show_admin_bar', 'admin_bar_for_admin_only', 99 ); function admin_bar_for_admin_only( $show_admin_bar ) { if ( $show_admin_bar && ! is_network_admin() ) { $show_admin_bar = false; } return $show_admin_bar; }
Ну и по аналогии можно отключать панель инструментов используя условные теги или другие проверки.
Удаление любых элементов (ссылок) из тулбара
Базовые элементы лучше удалять способом который описан выше (впрочем это не принципиально). А этим способом можно удалять дополнительные элементы, которые добавляет не WordPress.
Для удаления используется метод remove_menu() или remove_node() — это абсолютно одинаковые методы (алиасы).
Допустим какой-то плагин добавляет в меню элемент с ID menushka
и нам нужно удалить этот элемент:
// Удаляем пункт из тулбара add_action( 'wp_before_admin_bar_render', 'delete_item_from_toolbar', 99 ); function delete_item_from_toolbar() { global $wp_admin_bar; $wp_admin_bar->remove_menu('menushka'); }
Добавление элементов (ссылок) в тулбар
Build In PostДля добавления ссылок используется метод WP_Admin_Bar::add_menu() он же WP_Admin_Bar::add_node(). Добавление нужно делать на хуке admin_bar_menu.
Добавлять можно как ссылки верхнего уровня так и дочерние. Для примера давайте добавим ссылку и дочернюю ссылку в панель:
// Добавляет ссылку в админ бар add_action( 'admin_bar_menu', 'my_admin_bar_menu', 30 ); function my_admin_bar_menu( $wp_admin_bar ) { $wp_admin_bar->add_menu( array( 'id' => 'menu_id', 'title' => 'Внешняя ссылка', 'href' => 'http://example.com', ) ); // дочерняя ссылка $wp_admin_bar->add_menu( array( 'parent' => 'menu_id', // параметр id из первой ссылки 'id' => 'some_id', // свой id, чтобы можно было добавить дочерние ссылки 'title' => 'Дочерняя ссылка', 'href' => 'http://example.com/subpage', ) ); }
В результате получим:
Чтобы изменить положение всего блока ссылок, пункта (поставить его до или после какого-то блока), измените число 30 — чем больше, тем ближе к концу.
Еще пример: дочерняя ссылка в меню сайта на страницу плагинов
// дочерняя ссылка в меню сайта на страницу плагинов if( ! is_admin() ){ add_action( 'admin_bar_menu', function ( $wp_admin_bar ) { $wp_admin_bar->add_menu( array( 'parent' => 'site-name', // id родительского элемента 'id' => 'plugins_link', // свой id, чтобы можно было добавить дочерние ссылки 'title' => 'Плагины', 'href' => admin_url('plugins.php'), ) ); }, 100 ); }
Список всех возможных параметров смотрите в WP_Admin_Bar::add_menu().
Иконка (dashicon) для админ бара
Build In PostДля этого в параметре title
нужно добавить HTML тег dashicons, а также дополнительно к его классам добавить класс ab-icon
. Рассмотрим такой пример:
add_action( 'admin_bar_menu', 'add_toolbar_link', 70 ); function add_toolbar_link( $wp_admin_bar ){ $wp_admin_bar->add_menu( [ 'id' => 'chartlink', 'title' => '<span class="ab-icon dashicons-visibility" style="top:2px"></span><span class="ab-label">Views</span>', 'href' => '#', ] ); }
В результате мы получим:
Dashicons можно найти здесь: https://developer.wordpress.org/resource/dashicons/
Как узнать $id имеющегося элемента тулбара
Чтобы узнать $id имеющегося элемента панели, чтобы его удалить или чтобы добавить к нему дочерний элемент, посмотреть этот ID в исходном коде: он добавляется как суффикс в атрибут id тега LI: wp-admin-bar-{ID}
:
Можно еще найти элемент в коде WordPress или плагина, но это сложнее.
Убрать только отступ вверху у тулбара
Чтобы панель инструментов правильно отображалась WordPress добавляет отступ в 28px к HTML и BODY тегам. Если для каких-то целей нужно этот отступ убрать, используйте такой код:
add_action( 'admin_bar_init', function(){ remove_action( 'wp_head', '_admin_bar_bump_cb' ); // html margin bumps } );
Этот вариант удаляет саму функцию, которая добавляет css стили.
Добавление произвольного меню в панель инструментов
Build In PostЭтот пункт может быть практически незаменим, потому что кроме удобства он еще и добавляет функциональности.
Использовав следующий код мы регистрируем меню навигации wp_nav_menu и добавляем пункты из этого меню в панель инструментов.
Я написал этот код как замена своему уже устарелому плагину:
/** * toolbar nav menu - навигационное меню в тулбаре * v0.3 */ add_action( 'after_setup_theme', function() { register_nav_menu( 'toolbar', 'Панель инструментов' ); } ); add_action( 'admin_bar_menu', 'kama_add_toolbar_menu', 999 ); function kama_add_toolbar_menu( $toolbar ) { $locations = get_nav_menu_locations(); if( ! isset( $locations['toolbar'] ) ){ return; } $items = wp_get_nav_menu_items( $locations['toolbar'] ); if( ! $items ){ return; } foreach( $items as $item ){ $args = [ 'parent' => $item->menu_item_parent ? 'id_' . $item->menu_item_parent : false, 'id' => 'id_' . $item->ID, 'title' => $item->title, 'href' => $item->url, 'meta' => [ // 'html' - The html used for the node. // 'class' - The class attribute for the list item containing the link or text node. // 'rel' - The rel attribute. // 'onclick' - The onclick attribute for the link. This will only be set if the 'href' argument is present. // 'target' - The target attribute for the link. This will only be set if the 'href' argument is present. // 'title' - The title attribute. Will be set to the link or to a div containing a text node. // 'tabindex' - The tabindex attribute. Will be set to the link or to a div containing a text node. 'class' => implode( ' ', $item->classes ), 'title' => esc_attr( $item->description ), 'target' => $item->target, ], ]; $toolbar->add_node( $args ); } }
Как это работает.
Добавляете код в functions.php. Затем заходите в админку: Внешний вид > Меню
и создаете меню, добавляете в него любые ссылки и прикрепляете меню к области «Панель инструментов». Можно использовать несколько уровней, тогда верхний уровень будет главным в панели инструментов, а дополнительные станут выпадающим списком.
Ссылка на удаление записи в тулбаре
Ссылка на редактирование записи всегда находится в панели инструментов. Но если записи на сайте часто удаляются, то удобно иметь ссылку на удаление, чтобы для удаления не лазить в редактирование записи.
add_action( 'admin_bar_menu', 'kama_delete_toolbar_link', 90 ); function kama_delete_toolbar_link() { global $wp_admin_bar; if ( ! is_super_admin() || ! is_admin_bar_showing() ){ return; } $obj = get_queried_object(); if ( ! $obj || ! isset( $obj->post_type ) ){ return; } $dellink = get_delete_post_link( $obj->ID ); if( $dellink ){ $wp_admin_bar->add_menu( array( 'id' => 'delete', 'title' => EMPTY_TRASH_DAYS ? 'В корзину' : 'Удалить запись', 'href' => $dellink, ) ); } }
Здесь 90 - значит после ссылки на редактирование (у неё 80).
Показывать тулбар всегда
Редкий случай, но и такое может понадобится. Этот код будет всегда показывать панель инструментов, даже когда пользователь не авторизован. Но в этом случае там будет выводиться только ссылка «Войти». Она прописана в коде. По аналогии, можете добавить туда еще какие-нибудь ссылки:
// Всегда показывать админ бар add_filter( 'show_admin_bar', '__return_true' , 1000 ); add_action( 'admin_bar_menu', 'pjw_login_adminbar', 0 ); function pjw_login_adminbar( $wp_admin_bar) { if ( is_user_logged_in() ){ return; } $wp_admin_bar->add_menu( [ 'title' => 'Войти', 'href' => wp_login_url() ] ); remove_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 ); }
Заменим "Привет" на "Здравствуйте" в тулбаре
Не для всех сайтов может подходить неформальное слово "Привет", которое выводится в админ-баре. Иногда его нужно заменить, сделаем это:
add_action( 'admin_bar_menu', 'replace_wordpress_howdy', 25 ); /** * Изменяет "Привет" на "Здравствуйте" в тулбаре. * * @param WP_Admin_Bar $wp_admin_bar */ function replace_wordpress_howdy( $wp_admin_bar ) { $my_account = $wp_admin_bar->get_node( 'my-account' ); if ( isset( $my_account->title ) ) { $newtext = str_replace( 'Привет,', 'Здравствуйте,', $my_account->title ?? '' ); $wp_admin_bar->add_node( [ 'id' => 'my-account', 'title' => $newtext, ] ); } }
Multisite: вынос под-сайтов в главное меню админ бара
Если у вас мультисайт и в нем всего несколько под-сайтов, то гораздо удобнее если вынести все под-сайты в основное меню тулбара.
GitHub/** * Сutomize multisite admin bar. * Moves default nested multisite menu to main toolbar menu. */ class Multisite_Admin_Bar { public static function init(): void { add_action( 'admin_bar_menu', [ __CLASS__, 'cutomize_toolbar' ], 31 ); // 31 - after `wp_admin_bar_site_menu()` add_action( 'wp_head', [ __CLASS__, 'styles' ] ); add_action( 'admin_head', [ __CLASS__, 'styles' ] ); add_action( 'admin_bar_menu', [ __CLASS__, 'add_switch_node' ], 30 ); } public static function styles(): void { ?> <style id="cutomize_multisite_admin_bar"> #wp-admin-bar-network-admin .ab-icon:before{ color:#797c7d; } /* the color of the main icon */ #wpadminbar .hl-current-blog{ background-color: rgba(255 255 255 / 0.15); } </style> <?php } public static function cutomize_toolbar( \WP_Admin_Bar $toolbar ): void { // for multisite only if( ! $toolbar->get_node( 'site-name' ) ){ return; } // remove Multisite Language Switcher hook remove_action( 'admin_bar_menu', [ \lloc\Msls\MslsPlugin::class, 'update_adminbar' ], 999 ); // NOTE: the closure needed to access `WP_Admin_Bar->nodes` private property $callback = function(){ /** @var \WP_Admin_Bar $this */ /// remove nodes unset( $this->nodes['site-name'], // default current site node $this->nodes['my-sites-super-admin'], $this->nodes['my-sites'], $this->nodes['my-sites-list'] ); /// network-admin $net_admin = & $this->nodes['network-admin']; $net_admin->parent = ''; $net_admin->title = '<span class="ab-icon dashicons-admin-multisite"></span><span class="ab-label">Network</span>'; /// blogs foreach( $this->nodes as $key => $node ){ preg_match( '/blog-(\d+)(?:-(\w+))?/', $node->id, $mm ); $blog_id = (int) ( $mm[1] ?? 0 ); $type = $mm[2] ?? ''; if( $blog_id ){ // main: blog-1, blog-2 if( ! $type ){ // title preg_match( '~^<.*>~', $node->title, $mm ); $lang = langdata()->blog_id_lang( $blog_id ); $title_icon_html = $mm[0] ?? ''; $flag_img = sprintf( '<img src="%s" alt="%s">', langdata()->flag_url( $lang ), $lang ); $node->title = $title_icon_html . $flag_img . ' ' . strtoupper( $lang ); $node->href = is_admin() ? get_home_url( $blog_id ) : $node->href; $node->parent = ''; $node->meta['class'] = ( get_current_blog_id() === $blog_id ) ? 'hl-current-blog' : ''; } // comments: blog-1-c, blog-2-c if( 'c' === $type ){ unset( $this->nodes[ $key ] ); } } } }; $callback->call( $toolbar ); } public static function add_switch_node( \WP_Admin_Bar $toolbar ): void { global $pagenow; $url = $_SERVER['REQUEST_URI']; $url = str_starts_with( $url, '/ru' ) ? preg_replace( '~^/ru~', '', $url ) : "/ru$url"; if( 'post.php' === $pagenow && ( $post_id = (int) ( $_GET['post'] ?? 0 ) ) ){ $other_post_id = is_ru() ? get_ru_en_post_id( $post_id ) : get_en_ru_post_id( $post_id ); $url = $other_post_id ? str_replace( "post=$post_id", "post=$other_post_id", $url ) : ''; } $toolbar->add_menu( [ 'id' => 'switch_langs', 'title' => '<span class="ab-icon dashicons-controls-repeat"></span>', 'href' => $url, 'meta' => [ 'title' => 'Switch Curent Page to Opposite Lang', 'onclick' => 'alert("aaaaaaaaa")', ], ] ); } }
Плагины для панели инструментов (админ бара)
-
Clicky by Yoast - интегрирует сервис веб аналитики в админ бар.
-
What The File - отличный плагин для изучения иерархии шаблона. Он показывает какой файл шаблона отвечает за отображение страницы на который вы находитесь в текущий момент. Информация выводится в админ баре.
-
Admin Bar Disabler - позволяет удалять панель для указанных ролей: белые и черные списки. Или для указанных возможностей: также возможность можно поместить в белый и черный списки. В общем это плагин тотальной настройки пока админ бара.
- Генератор добавление пунктов в меню - сервис