{"id":261,"date":"2026-05-13T11:00:11","date_gmt":"2026-05-13T14:00:11","guid":{"rendered":"http:\/\/neodoor.neo\/?p=261"},"modified":"2026-05-21T09:02:53","modified_gmt":"2026-05-21T12:02:53","slug":"admin-menu-editor","status":"publish","type":"post","link":"https:\/\/www.portanova.com.br\/notebook\/admin-menu-editor\/","title":{"rendered":"[MU] Admin Menu Editor"},"content":{"rendered":"<h2>Aula: Editor de Menu Administrativo com MU-Plugin \u2013 Substituindo o Admin Menu Editor<\/h2>\n<p><strong>Objetivo:<\/strong> Substituir o plugin <code>admin-menu-editor<\/code> por um MU-Plugin enxuto, que permite reorganizar, renomear, ocultar e adicionar itens personalizados no menu lateral do WordPress (admin).<\/p>\n<p><strong>Contexto:<\/strong> 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\u00f3tulo, reordenar itens, ou adicionar um link externo. Tudo isso pode ser feito com poucas linhas de PHP, sem peso adicional.<\/p>\n<h3>Funcionalidades implementadas no nosso MU-Plugin<\/h3>\n<ul>\n<li>Reordenar itens do menu (ex: levar &#8220;Posts&#8221; para o topo)<\/li>\n<li>Renomear r\u00f3tulos de menus (ex: &#8220;Posts&#8221; \u2192 &#8220;Artigos&#8221;)<\/li>\n<li>Ocultar menus por papel do usu\u00e1rio (Administrador, Editor, Autor, etc.) ou por capacidade<\/li>\n<li>Adicionar separadores visuais no menu<\/li>\n<li>Adicionar links personalizados (URLs internas ou externas) com \u00edcones<\/li>\n<li>Remover submenus espec\u00edficos<\/li>\n<li>Totalmente configur\u00e1vel via array no pr\u00f3prio MU-Plugin<\/li>\n<\/ul>\n<h3>C\u00f3digo do MU-Plugin<\/h3>\n<p>Crie a pasta <code>wp-content\/mu-plugins\/neodoor-admin-menu-editor\/<\/code> e dentro dela o arquivo <code>neodoor-admin-menu-editor.php<\/code> com o conte\u00fado abaixo:<\/p>\n<pre><code>&lt;?php\n\/**\n * Plugin Name:  Neodoor Admin Menu Editor\n * Description:  Reorganize, renomeie, oculte ou adicione itens no menu administrativo do WordPress.\n * Version:      1.0\n * Author:       Reinaldo (Neodoor.neo)\n *\/\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nclass Neodoor_Admin_Menu_Editor {\n\n    private static $instance = null;\n\n    \/\/ Configura\u00e7\u00e3o do menu \u2013 edite este array conforme sua necessidade\n    private $menu_config = [\n        \/\/ Ordem personalizada (os slugs dos itens principais)\n        'order' =&gt; [\n            'index.php',                  \/\/ Dashboard\n            'edit.php',                   \/\/ Posts\n            'edit.php?post_type=page',    \/\/ P\u00e1ginas\n            'upload.php',                 \/\/ M\u00eddia\n            'separator1',                 \/\/ Separador (opcional)\n            'themes.php',                 \/\/ Apar\u00eancia\n            'plugins.php',                \/\/ Plugins\n            'users.php',                  \/\/ Usu\u00e1rios\n            'tools.php',                  \/\/ Ferramentas\n            'options-general.php',        \/\/ Configura\u00e7\u00f5es\n        ],\n        \n        \/\/ Renomear t\u00edtulos de menus (slug =&gt; novo t\u00edtulo)\n        'rename' =&gt; [\n            'edit.php'         =&gt; 'Artigos',\n            'edit.php?post_type=page' =&gt; 'P\u00e1ginas do Site',\n            'upload.php'       =&gt; 'Biblioteca',\n        ],\n        \n        \/\/ Ocultar menus para determinados pap\u00e9is (ou capacidades)\n        'hide_for_roles' =&gt; [\n            'plugins.php' =&gt; [ 'editor', 'author' ],   \/\/ Esconde Plugins para Editores e Autores\n            'tools.php'   =&gt; [ 'editor', 'author', 'contributor' ],\n        ],\n        \n        \/\/ Ocultar para capacidade espec\u00edfica (ex: s\u00f3 quem pode 'manage_options' v\u00ea)\n        'hide_by_capability' =&gt; [\n            'edit.php?post_type=acf-field-group' =&gt; 'manage_options', \/\/ Esconde ACF se n\u00e3o for admin\n        ],\n        \n        \/\/ Remover submenus espec\u00edficos (menu_slug =&gt; array de slugs de submenu)\n        'remove_submenus' =&gt; [\n            'themes.php' =&gt; [ 'theme-editor.php', 'customize.php' ], \/\/ Remove editor de temas e customizer\n            'plugins.php' =&gt; [ 'plugin-editor.php' ],                \/\/ Remove editor de plugins\n        ],\n        \n        \/\/ Adicionar links personalizados\n        'custom_links' =&gt; [\n            [\n                'title'      =&gt; 'Documenta\u00e7\u00e3o WP',\n                'url'        =&gt; 'https:\/\/wordpress.org\/documentation\/',\n                'capability' =&gt; 'read',\n                'icon'       =&gt; 'dashicons-media-document',\n                'position'   =&gt; 99, \/\/ ordem (quanto maior, mais abaixo)\n            ],\n            [\n                'title'      =&gt; 'Suporte Neodoor',\n                'url'        =&gt; '\/suporte', \/\/ URL interna\n                'capability' =&gt; 'read',\n                'icon'       =&gt; 'dashicons-sos',\n                'position'   =&gt; 100,\n            ],\n        ],\n    ];\n\n    public static function get_instance() {\n        if ( null === self::$instance ) {\n            self::$instance = new self();\n        }\n        return self::$instance;\n    }\n\n    private function __construct() {\n        add_action( 'admin_menu', [ $this, 'reorder_menu' ], 999 );\n        add_action( 'admin_menu', [ $this, 'rename_menu_items' ], 999 );\n        add_action( 'admin_menu', [ $this, 'hide_menu_items' ], 999 );\n        add_action( 'admin_menu', [ $this, 'remove_submenus' ], 999 );\n        add_action( 'admin_menu', [ $this, 'add_custom_links' ], 999 );\n    }\n\n    \/**\n     * Reordena o menu principal baseado na configura\u00e7\u00e3o 'order'\n     *\/\n    public function reorder_menu() {\n        global $menu, $submenu;\n\n        if ( empty( $this-&gt;menu_config['order'] ) ) {\n            return;\n        }\n\n        $ordered_menu = [];\n        $remaining = [];\n\n        \/\/ Mapeia menus existentes por slug\n        $menu_by_slug = [];\n        foreach ( $menu as $item ) {\n            if ( isset( $item[2] ) ) {\n                $menu_by_slug[ $item[2] ] = $item;\n            } else {\n                $remaining[] = $item;\n            }\n        }\n\n        \/\/ Adiciona na ordem especificada\n        foreach ( $this-&gt;menu_config['order'] as $slug ) {\n            if ( $slug === 'separator1' || $slug === 'separator2' ) {\n                \/\/ Cria separador\n                $ordered_menu[] = [ '', 'read', $slug, '', 'wp-menu-separator', '' ];\n            } elseif ( isset( $menu_by_slug[ $slug ] ) ) {\n                $ordered_menu[] = $menu_by_slug[ $slug ];\n                unset( $menu_by_slug[ $slug ] );\n            }\n        }\n\n        \/\/ Adiciona os itens que sobraram no final\n        $menu = array_merge( $ordered_menu, array_values( $menu_by_slug ), $remaining );\n    }\n\n    \/**\n     * Renomeia t\u00edtulos de menus\n     *\/\n    public function rename_menu_items() {\n        global $menu;\n\n        if ( empty( $this-&gt;menu_config['rename'] ) ) {\n            return;\n        }\n\n        foreach ( $menu as &amp;$item ) {\n            if ( isset( $item[2] ) &amp;&amp; isset( $this-&gt;menu_config['rename'][ $item[2] ] ) ) {\n                $item[0] = $this-&gt;menu_config['rename'][ $item[2] ];\n            }\n        }\n    }\n\n    \/**\n     * Oculta menus baseado em papel do usu\u00e1rio ou capacidade\n     *\/\n    public function hide_menu_items() {\n        global $menu, $submenu;\n\n        $user = wp_get_current_user();\n        $user_roles = (array) $user-&gt;roles;\n\n        \/\/ Oculta por papel\n        foreach ( $this-&gt;menu_config['hide_for_roles'] as $slug =&gt; $roles_to_hide ) {\n            if ( array_intersect( $user_roles, $roles_to_hide ) ) {\n                remove_menu_page( $slug );\n            }\n        }\n\n        \/\/ Oculta por capacidade\n        foreach ( $this-&gt;menu_config['hide_by_capability'] as $slug =&gt; $cap ) {\n            if ( ! current_user_can( $cap ) ) {\n                remove_menu_page( $slug );\n            }\n        }\n    }\n\n    \/**\n     * Remove submenus espec\u00edficos\n     *\/\n    public function remove_submenus() {\n        global $submenu;\n\n        if ( empty( $this-&gt;menu_config['remove_submenus'] ) ) {\n            return;\n        }\n\n        foreach ( $this-&gt;menu_config['remove_submenus'] as $parent_slug =&gt; $submenu_slugs ) {\n            if ( isset( $submenu[ $parent_slug ] ) ) {\n                foreach ( $submenu[ $parent_slug ] as $key =&gt; $item ) {\n                    if ( isset( $item[2] ) &amp;&amp; in_array( $item[2], $submenu_slugs ) ) {\n                        unset( $submenu[ $parent_slug ][ $key ] );\n                    }\n                }\n                \/\/ Reindexa\n                $submenu[ $parent_slug ] = array_values( $submenu[ $parent_slug ] );\n            }\n        }\n    }\n\n    \/**\n     * Adiciona links personalizados ao menu\n     *\/\n    public function add_custom_links() {\n        if ( empty( $this-&gt;menu_config['custom_links'] ) ) {\n            return;\n        }\n\n        foreach ( $this-&gt;menu_config['custom_links'] as $link ) {\n            if ( ! current_user_can( $link['capability'] ) ) {\n                continue;\n            }\n            add_menu_page(\n                $link['title'],\n                $link['title'],\n                $link['capability'],\n                $link['url'],\n                '',\n                $link['icon'],\n                $link['position']\n            );\n        }\n    }\n}\n\nNeodoor_Admin_Menu_Editor::get_instance();\n<\/code><\/pre>\n<h3>Instru\u00e7\u00f5es de instala\u00e7\u00e3o<\/h3>\n<ol>\n<li>Certifique-se de que o autoloader <code>loader.php<\/code> esteja presente em <code>\/wp-content\/mu-plugins\/<\/code> (conforme aula anterior).<\/li>\n<li>Crie a pasta <code>neodoor-admin-menu-editor<\/code> dentro de <code>\/mu-plugins\/<\/code>.<\/li>\n<li>Dentro dela, crie o arquivo <code>neodoor-admin-menu-editor.php<\/code> e cole o c\u00f3digo acima.<\/li>\n<li>Edite o array <code>$menu_config<\/code> conforme sua necessidade (ordem, renomea\u00e7\u00f5es, oculta\u00e7\u00f5es, etc.).<\/li>\n<li>Desative e remova o plugin <code>admin-menu-editor<\/code> da lista de plugins.<\/li>\n<\/ol>\n<h3>Configura\u00e7\u00e3o explicada (exemplos)<\/h3>\n<p>O cora\u00e7\u00e3o do plugin \u00e9 o array <code>$menu_config<\/code>. Veja como us\u00e1-lo:<\/p>\n<ul>\n<li><strong><code>order<\/code><\/strong>: lista de slugs dos menus na ordem desejada. Voc\u00ea pode usar slugs como <code>'index.php'<\/code>, <code>'edit.php'<\/code>, <code>'upload.php'<\/code>, <code>'separator1'<\/code> para adicionar um separador.<\/li>\n<li><strong><code>rename<\/code><\/strong>: associe um slug ao novo t\u00edtulo que aparecer\u00e1 no menu.<\/li>\n<li><strong><code>hide_for_roles<\/code><\/strong>: esconde um menu (slug) para determinados pap\u00e9is (array de strings: &#8216;administrator&#8217;, &#8216;editor&#8217;, &#8216;author&#8217;, &#8216;contributor&#8217;, &#8216;subscriber&#8217;).<\/li>\n<li><strong><code>hide_by_capability<\/code><\/strong>: esconde um menu se o usu\u00e1rio n\u00e3o tiver uma capacidade espec\u00edfica (ex: &#8216;manage_options&#8217;).<\/li>\n<li><strong><code>remove_submenus<\/code><\/strong>: remove submenus indesejados. A chave \u00e9 o slug do menu pai, o valor \u00e9 um array com os slugs dos submenus a remover.<\/li>\n<li><strong><code>custom_links<\/code><\/strong>: adiciona novos itens ao menu. Cada item pode ter: <code>title<\/code> (texto), <code>url<\/code> (link absoluto ou relativo), <code>capability<\/code>, <code>icon<\/code> (classe dashicons, ex: &#8216;dashicons-admin-links&#8217;), <code>position<\/code> (n\u00famero para ordena\u00e7\u00e3o).<\/li>\n<\/ul>\n<h3>Exemplos pr\u00e1ticos de configura\u00e7\u00e3o<\/h3>\n<pre><code>\/\/ Reordenar: Dashboard, Posts, Separador, M\u00eddia, Configura\u00e7\u00f5es\n'order' =&gt; [\n    'index.php',\n    'edit.php',\n    'separator1',\n    'upload.php',\n    'options-general.php',\n],\n\n\/\/ Renomear \"M\u00eddia\" para \"Arquivos\"\n'rename' =&gt; [\n    'upload.php' =&gt; 'Arquivos',\n],\n\n\/\/ Ocultar \"Plugins\" para qualquer usu\u00e1rio que n\u00e3o seja administrador\n'hide_by_capability' =&gt; [\n    'plugins.php' =&gt; 'manage_options',\n],\n\n\/\/ Remover o editor de temas dentro de Apar\u00eancia\n'remove_submenus' =&gt; [\n    'themes.php' =&gt; [ 'theme-editor.php' ],\n],\n<\/code><\/pre>\n<h3>Teste e verifica\u00e7\u00e3o<\/h3>\n<ul>\n<li>Fa\u00e7a login como Administrador: veja se a ordem e renomea\u00e7\u00f5es est\u00e3o aplicadas.<\/li>\n<li>Fa\u00e7a login como Editor (ou crie um usu\u00e1rio de teste): itens ocultos devem desaparecer.<\/li>\n<li>Os links personalizados devem aparecer na posi\u00e7\u00e3o definida.<\/li>\n<li>Submenus removidos n\u00e3o devem mais estar acess\u00edveis via URL direta (o WordPress os bloqueia).<\/li>\n<\/ul>\n<h3>Limita\u00e7\u00f5es e observa\u00e7\u00f5es<\/h3>\n<ul>\n<li>Alguns plugins adicionam menus dinamicamente com slugs que podem variar. Para descobrir o slug de um menu, use o inspetor de c\u00f3digo ou o plugin <strong>Query Monitor<\/strong>.<\/li>\n<li>A reordena\u00e7\u00e3o pode conflitar com outros plugins que tamb\u00e9m tentam reordenar o menu (ex: Jetpack, WooCommerce). Nesse caso, aumente a prioridade no hook <code>admin_menu<\/code> (o nosso j\u00e1 est\u00e1 em 999).<\/li>\n<li>Separadores n\u00e3o s\u00e3o suportados em todas as vers\u00f5es do WordPress, mas funcionam bem.<\/li>\n<li>Se voc\u00ea quiser ocultar um menu apenas para um papel espec\u00edfico, mas permitir para administradores, use <code>hide_for_roles<\/code> sem incluir &#8216;administrator&#8217;.<\/li>\n<\/ul>\n<h3>Dica extra: descubra slugs de menu rapidamente<\/h3>\n<p>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):<\/p>\n<pre><code>add_action( 'admin_head', function() {\n    global $menu;\n    echo '&lt;pre style=\"position:absolute;z-index:9999;background:#fff;border:1px solid #ccc;\"&gt;';\n    foreach ( $menu as $item ) {\n        if ( isset( $item[2] ) &amp;&amp; ! empty( $item[0] ) ) {\n            echo $item[0] . ' \u2192 ' . $item[2] . '&lt;br&gt;';\n        }\n    }\n    echo '&lt;\/pre&gt;';\n} );\n<\/code><\/pre>\n<h3>Registro no caderno<\/h3>\n<p>Data: <!--?php echo date('d\/m\/Y'); ?--><\/p>\n<p>Funcionalidade: Editor de menu administrativo (reordenar, renomear, ocultar, adicionar links)<\/p>\n<p>Plugins substitu\u00eddos: admin-menu-editor<\/p>\n<p>Complexidade: Baixa a m\u00e9dia (configura\u00e7\u00e3o via array)<\/p>\n<p>Observa\u00e7\u00e3o: Sempre teste em ambiente local antes de usar em produ\u00e7\u00e3o.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aula: Editor de Menu Administrativo com MU-Plugin \u2013 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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,4],"tags":[],"class_list":["post-261","post","type-post","status-publish","format-standard","hentry","category-lessons","category-pluginsmu"],"_links":{"self":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts\/261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/comments?post=261"}],"version-history":[{"count":0,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts\/261\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/media?parent=261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/categories?post=261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/tags?post=261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}