Aula: Editor de Menu Administrativo com MU-Plugin – Substituindo o Admin Menu Editor
Objetivo: Substituir o plugin admin-menu-editor por um MU-Plugin enxuto, que permite reorganizar, renomear, ocultar e adicionar itens personalizados no menu lateral do WordPress (admin).
Contexto: O plugin original oferece uma interface drag-and-drop, mas muitas vezes precisamos apenas de ajustes simples: esconder um menu para certos perfis, renomear um rótulo, reordenar itens, ou adicionar um link externo. Tudo isso pode ser feito com poucas linhas de PHP, sem peso adicional.
Funcionalidades implementadas no nosso MU-Plugin
- Reordenar itens do menu (ex: levar “Posts” para o topo)
- Renomear rótulos de menus (ex: “Posts” → “Artigos”)
- Ocultar menus por papel do usuário (Administrador, Editor, Autor, etc.) ou por capacidade
- Adicionar separadores visuais no menu
- Adicionar links personalizados (URLs internas ou externas) com ícones
- Remover submenus específicos
- Totalmente configurável via array no próprio MU-Plugin
Código do MU-Plugin
Crie a pasta wp-content/mu-plugins/neodoor-admin-menu-editor/ e dentro dela o arquivo neodoor-admin-menu-editor.php com o conteúdo abaixo:
<?php
/**
* Plugin Name: Neodoor Admin Menu Editor
* Description: Reorganize, renomeie, oculte ou adicione itens no menu administrativo do WordPress.
* Version: 1.0
* Author: Reinaldo (Neodoor.neo)
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Neodoor_Admin_Menu_Editor {
private static $instance = null;
// Configuração do menu – edite este array conforme sua necessidade
private $menu_config = [
// Ordem personalizada (os slugs dos itens principais)
'order' => [
'index.php', // Dashboard
'edit.php', // Posts
'edit.php?post_type=page', // Páginas
'upload.php', // Mídia
'separator1', // Separador (opcional)
'themes.php', // Aparência
'plugins.php', // Plugins
'users.php', // Usuários
'tools.php', // Ferramentas
'options-general.php', // Configurações
],
// Renomear títulos de menus (slug => novo título)
'rename' => [
'edit.php' => 'Artigos',
'edit.php?post_type=page' => 'Páginas do Site',
'upload.php' => 'Biblioteca',
],
// Ocultar menus para determinados papéis (ou capacidades)
'hide_for_roles' => [
'plugins.php' => [ 'editor', 'author' ], // Esconde Plugins para Editores e Autores
'tools.php' => [ 'editor', 'author', 'contributor' ],
],
// Ocultar para capacidade específica (ex: só quem pode 'manage_options' vê)
'hide_by_capability' => [
'edit.php?post_type=acf-field-group' => 'manage_options', // Esconde ACF se não for admin
],
// Remover submenus específicos (menu_slug => array de slugs de submenu)
'remove_submenus' => [
'themes.php' => [ 'theme-editor.php', 'customize.php' ], // Remove editor de temas e customizer
'plugins.php' => [ 'plugin-editor.php' ], // Remove editor de plugins
],
// Adicionar links personalizados
'custom_links' => [
[
'title' => 'Documentação WP',
'url' => 'https://wordpress.org/documentation/',
'capability' => 'read',
'icon' => 'dashicons-media-document',
'position' => 99, // ordem (quanto maior, mais abaixo)
],
[
'title' => 'Suporte Neodoor',
'url' => '/suporte', // URL interna
'capability' => 'read',
'icon' => 'dashicons-sos',
'position' => 100,
],
],
];
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action( 'admin_menu', [ $this, 'reorder_menu' ], 999 );
add_action( 'admin_menu', [ $this, 'rename_menu_items' ], 999 );
add_action( 'admin_menu', [ $this, 'hide_menu_items' ], 999 );
add_action( 'admin_menu', [ $this, 'remove_submenus' ], 999 );
add_action( 'admin_menu', [ $this, 'add_custom_links' ], 999 );
}
/**
* Reordena o menu principal baseado na configuração 'order'
*/
public function reorder_menu() {
global $menu, $submenu;
if ( empty( $this->menu_config['order'] ) ) {
return;
}
$ordered_menu = [];
$remaining = [];
// Mapeia menus existentes por slug
$menu_by_slug = [];
foreach ( $menu as $item ) {
if ( isset( $item[2] ) ) {
$menu_by_slug[ $item[2] ] = $item;
} else {
$remaining[] = $item;
}
}
// Adiciona na ordem especificada
foreach ( $this->menu_config['order'] as $slug ) {
if ( $slug === 'separator1' || $slug === 'separator2' ) {
// Cria separador
$ordered_menu[] = [ '', 'read', $slug, '', 'wp-menu-separator', '' ];
} elseif ( isset( $menu_by_slug[ $slug ] ) ) {
$ordered_menu[] = $menu_by_slug[ $slug ];
unset( $menu_by_slug[ $slug ] );
}
}
// Adiciona os itens que sobraram no final
$menu = array_merge( $ordered_menu, array_values( $menu_by_slug ), $remaining );
}
/**
* Renomeia títulos de menus
*/
public function rename_menu_items() {
global $menu;
if ( empty( $this->menu_config['rename'] ) ) {
return;
}
foreach ( $menu as &$item ) {
if ( isset( $item[2] ) && isset( $this->menu_config['rename'][ $item[2] ] ) ) {
$item[0] = $this->menu_config['rename'][ $item[2] ];
}
}
}
/**
* Oculta menus baseado em papel do usuário ou capacidade
*/
public function hide_menu_items() {
global $menu, $submenu;
$user = wp_get_current_user();
$user_roles = (array) $user->roles;
// Oculta por papel
foreach ( $this->menu_config['hide_for_roles'] as $slug => $roles_to_hide ) {
if ( array_intersect( $user_roles, $roles_to_hide ) ) {
remove_menu_page( $slug );
}
}
// Oculta por capacidade
foreach ( $this->menu_config['hide_by_capability'] as $slug => $cap ) {
if ( ! current_user_can( $cap ) ) {
remove_menu_page( $slug );
}
}
}
/**
* Remove submenus específicos
*/
public function remove_submenus() {
global $submenu;
if ( empty( $this->menu_config['remove_submenus'] ) ) {
return;
}
foreach ( $this->menu_config['remove_submenus'] as $parent_slug => $submenu_slugs ) {
if ( isset( $submenu[ $parent_slug ] ) ) {
foreach ( $submenu[ $parent_slug ] as $key => $item ) {
if ( isset( $item[2] ) && in_array( $item[2], $submenu_slugs ) ) {
unset( $submenu[ $parent_slug ][ $key ] );
}
}
// Reindexa
$submenu[ $parent_slug ] = array_values( $submenu[ $parent_slug ] );
}
}
}
/**
* Adiciona links personalizados ao menu
*/
public function add_custom_links() {
if ( empty( $this->menu_config['custom_links'] ) ) {
return;
}
foreach ( $this->menu_config['custom_links'] as $link ) {
if ( ! current_user_can( $link['capability'] ) ) {
continue;
}
add_menu_page(
$link['title'],
$link['title'],
$link['capability'],
$link['url'],
'',
$link['icon'],
$link['position']
);
}
}
}
Neodoor_Admin_Menu_Editor::get_instance();
Instruções de instalação
- Certifique-se de que o autoloader
loader.phpesteja presente em/wp-content/mu-plugins/(conforme aula anterior). - Crie a pasta
neodoor-admin-menu-editordentro de/mu-plugins/. - Dentro dela, crie o arquivo
neodoor-admin-menu-editor.phpe cole o código acima. - Edite o array
$menu_configconforme sua necessidade (ordem, renomeações, ocultações, etc.). - Desative e remova o plugin
admin-menu-editorda lista de plugins.
Configuração explicada (exemplos)
O coração do plugin é o array $menu_config. Veja como usá-lo:
order: lista de slugs dos menus na ordem desejada. Você pode usar slugs como'index.php','edit.php','upload.php','separator1'para adicionar um separador.rename: associe um slug ao novo título que aparecerá no menu.hide_for_roles: esconde um menu (slug) para determinados papéis (array de strings: ‘administrator’, ‘editor’, ‘author’, ‘contributor’, ‘subscriber’).hide_by_capability: esconde um menu se o usuário não tiver uma capacidade específica (ex: ‘manage_options’).remove_submenus: remove submenus indesejados. A chave é o slug do menu pai, o valor é um array com os slugs dos submenus a remover.custom_links: adiciona novos itens ao menu. Cada item pode ter:title(texto),url(link absoluto ou relativo),capability,icon(classe dashicons, ex: ‘dashicons-admin-links’),position(número para ordenação).
Exemplos práticos de configuração
// Reordenar: Dashboard, Posts, Separador, Mídia, Configurações
'order' => [
'index.php',
'edit.php',
'separator1',
'upload.php',
'options-general.php',
],
// Renomear "Mídia" para "Arquivos"
'rename' => [
'upload.php' => 'Arquivos',
],
// Ocultar "Plugins" para qualquer usuário que não seja administrador
'hide_by_capability' => [
'plugins.php' => 'manage_options',
],
// Remover o editor de temas dentro de Aparência
'remove_submenus' => [
'themes.php' => [ 'theme-editor.php' ],
],
Teste e verificação
- Faça login como Administrador: veja se a ordem e renomeações estão aplicadas.
- Faça login como Editor (ou crie um usuário de teste): itens ocultos devem desaparecer.
- Os links personalizados devem aparecer na posição definida.
- Submenus removidos não devem mais estar acessíveis via URL direta (o WordPress os bloqueia).
Limitações e observações
- Alguns plugins adicionam menus dinamicamente com slugs que podem variar. Para descobrir o slug de um menu, use o inspetor de código ou o plugin Query Monitor.
- A reordenação pode conflitar com outros plugins que também tentam reordenar o menu (ex: Jetpack, WooCommerce). Nesse caso, aumente a prioridade no hook
admin_menu(o nosso já está em 999). - Separadores não são suportados em todas as versões do WordPress, mas funcionam bem.
- Se você quiser ocultar um menu apenas para um papel específico, mas permitir para administradores, use
hide_for_rolessem incluir ‘administrator’.
Dica extra: descubra slugs de menu rapidamente
Adicione este snippet temporariamente em um MU-Plugin ou no tema para listar todos os slugs na tela de admin (lembre-se de remover depois):
add_action( 'admin_head', function() {
global $menu;
echo '<pre style="position:absolute;z-index:9999;background:#fff;border:1px solid #ccc;">';
foreach ( $menu as $item ) {
if ( isset( $item[2] ) && ! empty( $item[0] ) ) {
echo $item[0] . ' → ' . $item[2] . '<br>';
}
}
echo '</pre>';
} );
Registro no caderno
Data:
Funcionalidade: Editor de menu administrativo (reordenar, renomear, ocultar, adicionar links)
Plugins substituídos: admin-menu-editor
Complexidade: Baixa a média (configuração via array)
Observação: Sempre teste em ambiente local antes de usar em produção.