Personalização do admin WordPress: O guia do programador 2026

Personalização do admin WordPress: O guia do programador 2026

Última verificação: 14 de outubro de 2026
21 min de leitura
Tutorial
Desenvolvedor full-stack
500+ projetos WP

Quando entrega um site WordPress a um cliente, o painel padrão é frequentemente avassalador. Está cheio de avisos de upsell, menus confusos como “Comentários” (quando os comentários estão desativados) e jargão técnico que gera pedidos de suporte em vez de trabalho de conteúdo.

Um dashboard genérico diz “instalei um tema”. Um dashboard personalizado diz “construí uma ferramenta de trabalho para os papéis que realmente iniciam sessão”.

Este guia é para programadores que entregam sites a editores, gestores de loja e papéis de cliente. Percorre o carregamento de CSS e JS do admin, a limpeza de menus, as verificações de capabilities, os papéis próprios, as páginas de definições, o esquema de cores, o ecrã de início de sessão, o isolamento num must-use-plugin e a forma de não estragar os ecrãs do núcleo. As referências oficiais para carregar recursos e construir menus são admin_enqueue_scripts e admin_menu.

#Porque a personalização do admin reduz o suporte

Depois da entrega de uma loja WooCommerce feita com um construtor de páginas, o cliente vê muitas vezes dezenas de entradas de menu e usa meia dúzia. O resto gera perguntas: “posso clicar em Temas?”, “o que é o ACF?”, “porque vejo WooCommerce > Estado?”.

Retirar Ferramentas, Definições e os editores de ficheiros a todos os que não têm manage_options não tem a ver com cores mais bonitas. Os caminhos perigosos desaparecem da vista de quem não tem acesso total.

O segundo ganho é a integração de novos utilizadores. Em vez de uma hora de “não clique aqui”, mostra uma página de Suporte com documentação, contacto e uma lista curta de verificação para publicar. Isto é white-label como produto, não apenas uma troca de logótipo.

#Personalização do admin num must-use-plugin em vez do functions.php

Não coloque a personalização do admin no functions.php do tema filho. Quando o cliente troca de tema, as regras de menu, o carregamento de recursos e as verificações de capabilities desaparecem com ele. O código da agência que tem de sobreviver a uma troca de tema pertence a um must-use-plugin em wp-content/mu-plugins/.

Uma estrutura típica:

wp-content/mu-plugins/
  wppoland-admin-ux.php          # ficheiro de arranque (carrega a pasta)
  wppoland-admin-ux/
    menu.php
    enqueue.php
    capabilities.php
    dashboard.php

O ficheiro de arranque na raiz de mu-plugins/ é carregado automaticamente. Inclui apenas os ficheiros da subpasta. A vantagem é que o código corre sempre, independentemente dos plugins normais ativos, e pode versionar a pasta inteira sem que alguém a desative no ecrã de Plugins.

<?php
/**
 * Plugin Name: WPPoland Admin UX
 * Description: Limpeza de menus, carregamento de recursos e páginas de suporte para papéis de cliente.
 * Author: wppoland.com
 */

declare(strict_types=1);

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

$dir = __DIR__ . '/wppoland-admin-ux';
require_once $dir . '/menu.php';
require_once $dir . '/enqueue.php';
require_once $dir . '/capabilities.php';
require_once $dir . '/dashboard.php';

Teste sempre com uma conta própria que tenha o papel do cliente (Editor, Gestor de loja ou um papel personalizado). Se ficar com a sessão de Super Admin no staging, não vê os erros que acabou de “corrigir” para o cliente.

Se o projeto já tem um plugin da agência com autoload do Composer, o ficheiro de arranque must-use pode limitar-se a carregar esse pacote. A ideia mantém-se: a experiência do admin não pode morrer quando, num redesign, um tema filho do Elementor é substituído.

Mantenha os ficheiros pequenos. Um para o menu, outro para os recursos, outro para os bloqueios. Quem tiver de descobrir mais tarde porque desapareceu o menu do ACF não deve ter de vasculhar um functions.php com 800 linhas.

#O que distingue um must-use-plugin de um plugin normal

O manual de administração avançada enumera as diferenças, e várias mudam a forma de escrever o código do admin:

  • Os must-use-plugins estão ativos em todos os sites da instalação e não podem ser desativados no wp-admin.
  • O PHP carrega-os por ordem alfabética, antes dos plugins normais.
  • Os ficheiros em subpastas não são incluídos automaticamente. É por isso que a estrutura acima precisa de um ficheiro de arranque na raiz.
  • Não aparecem na lista por omissão do ecrã de Plugins, mas numa lista Must-Use separada que só os utilizadores com acesso a Plugins veem.
  • Não aparecem nas notificações de atualização, por isso as novas versões ficam ao seu cuidado.
  • Os hooks de ativação não são executados para plugins na pasta must-use.

O último ponto é o que mais surpreende. O código que um plugin normal poria em register_activation_hook, como a criação de papéis, precisa num must-use-plugin da sua própria verificação de versão. As secções seguintes mostram o padrão.

#Como verificar capabilities antes de alterar o menu do admin

remove_menu_page e add_menu_page são API de visibilidade. Não substituem o controlo de acesso. Um utilizador esperto que conheça o URL continua a abrir tools.php ou /wp-admin/options-general.php se a capability o permitir.

Regras que aguentam em produção:

  1. Verifique permissões (capabilities), não IDs: current_user_can( 'manage_options' ) ou uma capability mais específica, antes de esconder menus aos papéis de cliente.
  2. Nunca esconda menus a Administradores, que são quem tem de depurar o site. Um administrador sem menu visível custa mais tempo do que poupa.
  3. Para bloquear realmente o acesso, verifique as permissões em current_screen ou admin_init e responda com wp_die() ou um redirecionamento com explicação, não apenas com display: none em CSS.

Em redações onde colaboradores externos e editores do quadro partilham o site, compensa um papel próprio com edit_posts e upload_files, sem install_plugins nem edit_themes. A limpeza do menu passa então a refletir esse papel, em vez de uma longa lista de exceções por ID de utilizador. get_role( 'editor' )->remove_cap( '...' ) pertence a uma migração pontual ou a um comando de CLI, não a um hook que corre em todas as páginas do admin.

/**
 * Bloqueia o acesso direto por URL às Ferramentas para não administradores.
 */
function wppoland_block_tools_screen(): void {
	if ( ! is_admin() || wp_doing_ajax() ) {
		return;
	}

	if ( current_user_can( 'manage_options' ) ) {
		return;
	}

	$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
	if ( ! $screen || 'tools' !== $screen->id ) {
		return;
	}

	wp_die(
		esc_html__( 'Não tem acesso a este ecrã.', 'wppoland-admin-ux' ),
		esc_html__( 'Acesso negado', 'wppoland-admin-ux' ),
		[ 'response' => 403 ]
	);
}
add_action( 'current_screen', 'wppoland_block_tools_screen' );

Os nomes das capabilities são o contrato. Os IDs de utilizador mudam, mas o Gestor de loja mantém manage_woocommerce. Construa as regras à volta de capabilities, não do utilizador com o ID 12.

#Papel de cliente próprio com add_role e map_meta_cap

Os papéis ficam guardados na base de dados, não no código. A referência de add_role indica que a função termina e devolve null se o papel já existir. Uma lista de capabilities alterada não tem efeito enquanto o papel não for removido e criado de novo. Sem uma verificação de versão isso aconteceria em cada pedido, e como os must-use-plugins não têm hook de ativação, um valor de versão guardado é a proteção mais simples.

function wppoland_register_client_role(): void {
	if ( '2' === get_option( 'wppoland_roles_version' ) ) {
		return;
	}

	remove_role( 'client_manager' );
	add_role(
		'client_manager',
		'Editor do cliente',
		[
			'read'                 => true,
			'edit_posts'           => true,
			'edit_published_posts' => true,
			'publish_posts'        => true,
			'delete_posts'         => true,
			'edit_pages'           => true,
			'edit_published_pages' => true,
			'edit_others_pages'    => true,
			'publish_pages'        => true,
			'upload_files'         => true,
			'moderate_comments'    => true,
		]
	);

	update_option( 'wppoland_roles_version', '2' );
}
add_action( 'init', 'wppoland_register_client_role' );

As capabilities que não estão na lista, o papel não as tem. É mais seguro do que definir manage_options => false de forma explícita, porque uma chave esquecida não abre nada. Quando a lista mudar, aumente o valor de versão.

Há páginas que o cliente não deve editar mesmo que o papel tenha edit_others_pages, normalmente a página inicial. O filtro map_meta_cap traduz meta-capabilities como edit_post em capabilities primitivas, e aí pode acrescentar do_not_allow para uma página concreta:

function wppoland_protect_front_page( array $caps, string $cap, int $user_id, array $args ): array {
	if ( ! in_array( $cap, [ 'edit_post', 'delete_post' ], true ) || empty( $args[0] ) ) {
		return $caps;
	}

	$front_page = (int) get_option( 'page_on_front' );

	if ( $front_page && (int) $args[0] === $front_page && ! user_can( $user_id, 'manage_options' ) ) {
		$caps[] = 'do_not_allow';
	}

	return $caps;
}
add_filter( 'map_meta_cap', 'wppoland_protect_front_page', 10, 4 );

A vantagem em relação a esconder o link Editar é que a regra vale em todo o lado: na lista de páginas, no editor de blocos, na REST API e na edição rápida.

#Como limpar o menu de admin do WordPress

O primeiro passo visível é remove_menu_page em admin_menu com prioridade tardia, para que os plugins já tenham registado os seus menus. A maioria dos clientes não precisa de ver “Ferramentas” ou “Definições”.

/**
 * Limpar o menu de admin para não administradores.
 */
function wppoland_clean_admin_menu(): void {
	if ( current_user_can( 'manage_options' ) ) {
		return;
	}

	remove_menu_page( 'tools.php' );                // Ferramentas
	remove_menu_page( 'options-general.php' );      // Definições
	remove_menu_page( 'edit-comments.php' );        // Comentários
	remove_menu_page( 'edit.php?post_type=acf-field-group' ); // ACF

	remove_submenu_page( 'themes.php', 'theme-editor.php' );
	remove_submenu_page( 'plugins.php', 'plugin-editor.php' );
}
add_action( 'admin_menu', 'wppoland_clean_admin_menu', 999 );

Aviso: remove_menu_page apenas esconde o link. Combine-o sempre com um bloqueio por capability onde o caminho é perigoso (editores de ficheiros, grupos de campos ACF, instalação de plugins).

Em lojas WooCommerce é comum deixar ao Gestor de loja os Produtos, as Encomendas e os Cupões, mas retirar os submenus de Estado e Extensões. Isso corta as perguntas do tipo “posso atualizar este plugin?” sem tirar o que a operação diária precisa.

A prioridade 999 é intencional. Muitos plugins registam menus em admin_menu com a prioridade por omissão, 10. Se a limpeza correr cedo demais, o slug ainda não existe e remove_menu_page não faz nada. Registe temporariamente $GLOBALS['menu'] no staging se não tiver a certeza do slug que um plugin usa. O ACF, o Yoast e o WooCommerce têm caminhos pouco óbvios.

Não retire a Biblioteca multimédia a editores que carregam imagens de facto. É a limpeza excessiva clássica: o painel fica arrumado e no dia seguinte chega o pedido a dizer que falta “Carregar”. Limpe primeiro as ferramentas técnicas e os caminhos de conteúdo por último.

#Como adicionar páginas de menu personalizadas no admin

Não use frameworks de opções de tema se não precisar. A API nativa é rápida e leve.

function wppoland_register_support_page(): void {
	add_menu_page(
		'Suporte ao cliente',       // Título da página
		'Suporte',                  // Título do menu
		'edit_posts',               // Permissão
		'wppoland-support',         // Slug
		'wppoland_render_support',  // Callback
		'dashicons-sos',            // Ícone
		90                          // Posição
	);
}
add_action( 'admin_menu', 'wppoland_register_support_page' );

function wppoland_render_support(): void {
	if ( ! current_user_can( 'edit_posts' ) ) {
		wp_die( esc_html__( 'Acesso negado', 'wppoland-admin-ux' ) );
	}
	?>
	<div class="wrap">
		<h1>Precisa de ajuda?</h1>
		<div class="card">
			<h2>Contacte o seu programador</h2>
			<p>Email: <a href="mailto:[email protected]">dev@wppoland.com</a></p>
		</div>
	</div>
	<?php
}

Mantenha o callback simples: links para documentação, uma lista de verificação para publicar e o estado das cópias de segurança, se já tiver esse dado. Não construa um mini CMS dentro da página de Suporte.

Use add_submenu_page sob um menu de tipo de conteúdo existente quando a ajuda diz respeito a um só tipo (por exemplo “Eventos > Ajuda”). Reserve os menus de topo para aquilo que o cliente abre todas as semanas. Ícones de topo a mais recriam o caos que acabou de limpar.

#Página de definições para o cliente com a Settings API

Quando o cliente tem de alterar alguns valores sozinho, como o telefone de suporte ou os links para redes sociais, não precisa de acesso às Definições. Uma página construída com a Settings API mostra-lhe apenas esses campos. Segundo o manual, o WordPress trata então de guardar os dados submetidos, acrescenta nonces e envia o formulário através de wp-admin/options.php, que verifica as capabilities com rigor.

function wppoland_register_client_settings(): void {
	register_setting(
		'wppoland_client',
		'wppoland_support_phone',
		[
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => '',
		]
	);

	add_settings_section( 'wppoland_contact', 'Contacto', '__return_false', 'wppoland-client-settings' );

	add_settings_field(
		'wppoland_support_phone',
		'Telefone de suporte',
		'wppoland_render_phone_field',
		'wppoland-client-settings',
		'wppoland_contact'
	);
}
add_action( 'admin_init', 'wppoland_register_client_settings' );

function wppoland_render_phone_field(): void {
	printf(
		'<input type="text" name="wppoland_support_phone" value="%s" class="regular-text">',
		esc_attr( (string) get_option( 'wppoland_support_phone', '' ) )
	);
}

function wppoland_add_client_settings_page(): void {
	add_menu_page(
		'Definições do site',
		'Site',
		'edit_pages',
		'wppoland-client-settings',
		'wppoland_render_client_settings',
		'dashicons-admin-generic',
		91
	);
}
add_action( 'admin_menu', 'wppoland_add_client_settings_page' );

function wppoland_render_client_settings(): void {
	?>
	<div class="wrap">
		<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
		<?php settings_errors(); ?>
		<form action="options.php" method="post">
			<?php
			settings_fields( 'wppoland_client' );
			do_settings_sections( 'wppoland-client-settings' );
			submit_button();
			?>
		</form>
	</div>
	<?php
}

add_filter( 'option_page_capability_wppoland_client', fn() => 'edit_pages' );

A última linha é a que costuma faltar. O ficheiro do núcleo wp-admin/options.php indica que os grupos de opções de todas as definições registadas exigem manage_options por omissão, e que o filtro option_page_capability_{$option_page} muda essa exigência para um grupo. Sem o filtro, o editor vê a página, preenche o campo e recebe um erro ao guardar. O filtro abre apenas o grupo wppoland_client, não o resto das Definições.

#Carregar CSS e JS do admin com admin_enqueue_scripts e não com admin_head

O admin_head com um bloco <style> em linha funciona em demonstrações, mas escala mal: sem versões, com invalidação de cache incómoda e com apresentação misturada no PHP. Use admin_enqueue_scripts, carregue os seus próprios ficheiros e limite-os aos ecrãs que precisam deles.

function wppoland_admin_assets( string $hook_suffix ): void {
	// Apenas as nossas páginas e o painel, não todos os ecrãs do núcleo.
	$allowed = [
		'index.php',
		'toplevel_page_wppoland-support',
	];

	if ( ! in_array( $hook_suffix, $allowed, true ) ) {
		return;
	}

	$base = plugin_dir_url( __FILE__ );
	$ver  = '2026.09.21';

	wp_enqueue_style(
		'wppoland-admin-ux',
		$base . 'assets/admin.css',
		[],
		$ver
	);

	wp_enqueue_script(
		'wppoland-admin-ux',
		$base . 'assets/admin.js',
		[ 'jquery' ],
		$ver,
		true
	);

	wp_localize_script(
		'wppoland-admin-ux',
		'wppolandAdminUx',
		[
			'ajaxUrl' => admin_url( 'admin-ajax.php' ),
			'nonce'   => wp_create_nonce( 'wppoland_admin_ux' ),
		]
	);
}
add_action( 'admin_enqueue_scripts', 'wppoland_admin_assets' );

O $hook_suffix é a chave para não estragar os ecrãs do núcleo. Uma folha de estilos global que esconde .notice em todas as páginas do admin remove também os avisos do núcleo sobre atualizações de segurança críticas. Esconder avisos de plugins incómodos com .notice.is-dismissible { display: none; } tem o mesmo problema. Limite os seletores aos seus próprios contentores (.wppoland-support-wrap) ou aos seus próprios sufixos de hook.

Para que as cores correspondam à marca do seu cliente (ou da sua agência), sobreponha poucos seletores documentados e teste o editor clássico e o editor de blocos. O Gutenberg tem a sua própria interface: um #wpadminbar { background } abrangente não faz mal, mas !important em .components-button é receita para um editor estragado.

/* assets/admin.css: âmbito estreito */
#wpadminbar {
	background: #1f2937;
}

#toplevel_page_wppoland-support .wp-menu-image::before {
	color: #059669;
}

.wppoland-support-wrap .card {
	max-width: 40rem;
}

Se o admin.js comunicar com a REST API, use wp_create_nonce( 'wp_rest' ) ou o seu próprio nonce localizado como no exemplo. “Só utilizadores com sessão iniciada” não chega sem verificar o nonce no servidor. Evite também chamar wp_print_scripts diretamente no callback de add_menu_page, porque quebra a ordem das dependências.

#Esquema de cores próprio para o admin WordPress com wp_admin_css_color

As cores do menu lateral e da barra de ferramentas vêm do esquema de cores que cada utilizador escolhe no seu perfil. Em vez de as sobrepor com !important, pode registar o seu próprio esquema com wp_admin_css_color. A função recebe uma chave única, um nome, o URL do ficheiro CSS com o esquema, uma lista de cores que servem de pré-visualização no perfil e, opcionalmente, as cores dos ícones SVG (base, focus e current).

function wppoland_register_admin_scheme(): void {
	wp_admin_css_color(
		'wppoland',
		'WPPoland',
		plugin_dir_url( __FILE__ ) . 'assets/admin-colors.css',
		[ '#1f2937', '#059669', '#d1fae5', '#ffffff' ],
		[
			'base'    => '#d1d5db',
			'focus'   => '#ffffff',
			'current' => '#ffffff',
		]
	);
}
add_action( 'admin_init', 'wppoland_register_admin_scheme' );

O núcleo regista os seus próprios esquemas no mesmo hook: register_admin_color_schemes está ligado a admin_init com prioridade 1 em wp-admin/includes/admin-filters.php. A escolha fica guardada como a opção de utilizador admin_color, e o admin recebe a classe de body admin-color- seguida da chave, por isso pode dirigir regras adicionais apenas ao seu esquema.

Com o filtro get_user_option_admin_color pode impor o esquema a todos, mas assim tira a escolha aos utilizadores. Há quem escolha um esquema porque o contraste lhe é mais legível. O seu esquema como mais uma opção é uma predefinição mais segura.

#Erros comuns na personalização do admin WordPress

Três erros que se repetem em produção:

  1. Esconder todos os avisos. .notice { display: none } remove tanto o spam de plugins como os avisos críticos do núcleo. Filtre pela classe do plugin ou use remove_action sobre callbacks conhecidos de admin_notices.
  2. Retirar Plugins ou Atualizações a todos. Os papéis de cliente não devem instalar plugins. O administrador tem de o fazer. Se esconder Atualizações a quem tem manage_options, perde a visibilidade das versões de segurança.
  3. Reescrever ecrãs da Settings API. Não substitua options-general.php por uma página “simplificada” própria, a não ser que replique todas as opções necessárias e a sua validação. Uma cópia incompleta estraga as ligações permanentes, o URL do site e o idioma.

Ao personalizar o editor de blocos, use enqueue_block_editor_assets separadamente de admin_enqueue_scripts e carregue apenas o que o editor precisa.

Um teste de regressão prático: abra a lista de artigos, o Gutenberg numa página, a Biblioteca multimédia, WooCommerce > Encomendas e a sua página de Suporte, como Administrador e como Editor. Se algum desses ecrãs perder botões, avisos ou navegação por teclado, reverta o CSS antes da entrega.

#Personalizar a barra de ferramentas (barra de admin)

A Toolbar é visível no frontend para utilizadores com sessão iniciada. É um local privilegiado para ações rápidas como “Limpar cache” ou “Editar no Page Builder”, sempre com nonce e verificação de capability, e não com um URL GET aberto.

function wppoland_customize_toolbar( WP_Admin_Bar $wp_admin_bar ): void {
	// Remover o logótipo WordPress
	$wp_admin_bar->remove_node( 'wp-logo' );

	if ( ! current_user_can( 'manage_options' ) ) {
		return;
	}

	$wp_admin_bar->add_node(
		[
			'id'    => 'wppoland-clear-cache',
			'title' => 'Limpar cache',
			'href'  => wp_nonce_url(
				admin_url( 'admin-post.php?action=wppoland_clear_cache' ),
				'wppoland_clear_cache'
			),
			'meta'  => [ 'title' => 'Limpar a cache de objetos' ],
		]
	);
}
add_action( 'admin_bar_menu', 'wppoland_customize_toolbar', 999 );

Trate admin_post_wppoland_clear_cache com check_admin_referer e redirecione de volta. Sem nonce, o botão rápido torna-se um alvo de CSRF. Se a barra tiver de desaparecer no frontend para certos papéis, há um guia próprio para ocultar a barra de administração a não administradores.

#Como personalizar widgets do painel e o ecrã de boas-vindas

Quando um cliente inicia sessão, aterra no painel. Os widgets padrão (“Eventos WordPress”, “Rascunho rápido”) são geralmente inúteis para ele. Substitua-os por um widget de estado com aquilo que o cliente pergunta de facto: cópias de segurança, disponibilidade, último conteúdo publicado.

function wppoland_dashboard_widgets(): void {
	// Remover padrões
	remove_meta_box( 'dashboard_primary', 'dashboard', 'side' );     // Eventos e notícias
	remove_meta_box( 'dashboard_quick_press', 'dashboard', 'side' ); // Rascunho rápido

	wp_add_dashboard_widget(
		'wppoland_status_widget',
		'Estado do site',
		'wppoland_render_status_widget'
	);
}
add_action( 'wp_dashboard_setup', 'wppoland_dashboard_widgets' );

function wppoland_render_status_widget(): void {
	echo '<p><strong>WordPress</strong>: ' . esc_html( get_bloginfo( 'version' ) ) . '</p>';
	echo '<p><strong>Cópias de segurança</strong>: confirme a última tarefa no plugin de backup</p>';
	echo '<p><a href="' . esc_url( admin_url( 'admin.php?page=wppoland-support' ) ) . '">Abrir suporte</a></p>';
}

Não escreva “Atualizado” com um visto verde se o widget não lê a versão real. Um widget de estado que mente é pior do que nenhum. Os callbacks devem ser baratos: não chame API externas de forma síncrona ao desenhar o painel, guarde o resultado num transient e mostre quando foi obtido.

#O que fazem realmente os widgets por omissão do painel

Uma razão habitual para remover os widgets por omissão é a velocidade. O código-fonte de wp-admin/includes/dashboard.php mostra que o ganho é pequeno:

  • Eventos e notícias do WordPress (dashboard_primary) carrega o feed através de um widget com cache. O HTML gerado fica num transient por idioma e, quando essa cache está vazia, o widget mostra um indicador de carregamento e vai buscar o conteúdo por AJAX, em vez de atrasar a página.
  • Rascunho rápido (dashboard_quick_press) reutiliza um único rascunho automático por utilizador, cujo ID fica na opção de utilizador dashboard_quick_press_last_post_id. Os rascunhos automáticos com mais de sete dias são apagados por wp_delete_auto_drafts, que corre no evento agendado wp_scheduled_auto_draft_delete.
  • Estado de saúde do site (dashboard_site_health) lê um resultado guardado no transient health-check-site-status-result, em vez de correr todos os testes a cada visita.

O argumento para os remover é o foco, não a velocidade. Pondere manter a saúde do site para os administradores, porque mostra avisos sobre a versão do PHP e módulos em falta que de outra forma passam despercebidos.

O ecrã de início de sessão é a primeira coisa que o cliente vê todos os dias. Três hooks de wp-login.php cobrem quase tudo:

  • login_enqueue_scripts (desde a versão 3.1) é o hook para folhas de estilo e scripts no ecrã de início de sessão, o equivalente de admin_enqueue_scripts no wp-admin.
  • login_headerurl controla para onde aponta o logótipo. Por omissão é wordpress.org.
  • login_headertext (desde a versão 5.2) controla o texto do link do logótipo. O filtro antigo login_headertitle está obsoleto desde a 5.2, com a nota de que um atributo title no logótipo não é recomendado por razões de acessibilidade.
function wppoland_login_assets(): void {
	wp_enqueue_style(
		'wppoland-login',
		plugin_dir_url( __FILE__ ) . 'assets/login.css',
		[],
		'2026.10.14'
	);
}
add_action( 'login_enqueue_scripts', 'wppoland_login_assets' );

add_filter( 'login_headerurl', fn() => home_url( '/' ) );
add_filter( 'login_headertext', fn() => get_bloginfo( 'name' ) );
/* assets/login.css */
.login h1 a {
	background-image: url("../img/logotipo-cliente.svg");
	background-size: contain;
	width: 100%;
	height: 80px;
}

Os leitores de ecrã leem o texto do link, por isso o nome do site é melhor escolha do que uma cadeia vazia. Teste o ecrã com um plugin de dois fatores ou SSO ativo, porque estes acrescentam campos próprios que um CSS demasiado apertado pode empurrar para fora do ecrã. Outras técnicas para o próprio formulário estão no guia sobre como personalizar o login do WordPress.

#O que verificar antes de entregar um admin WordPress personalizado

Percorra esta lista com uma conta de papel de cliente no staging:

  1. O menu mostra apenas o que o papel precisa; o administrador continua a ver tudo.
  2. Os URLs diretos para Ferramentas, Definições ou o editor de ficheiros estão bloqueados onde é suposto.
  3. O CSS e o JS do admin carregam apenas nos $hook_suffix permitidos.
  4. O editor de blocos e a Biblioteca multimédia funcionam sem botões estragados nem avisos escondidos.
  5. As ações da barra de ferramentas exigem nonce e a capability certa.
  6. O código vive num must-use-plugin (ou num plugin da agência), não no tema.
  7. A página de definições guarda com o papel do cliente, não só como administrador.
  8. O logótipo do início de sessão aponta para o site e tem um texto de link legível.

Documente no README do projeto que menus estão escondidos por papel e que must-use-plugin é dono das regras. O próximo programador não deve ter de reconstruir os callbacks de admin_menu para perceber porque falta Definições ao Gestor de loja.

#Como aplicar white-label ao admin do WordPress em 90 dias

Este calendário ordena o trabalho de marca e segurança da área de administração:

  • Dias 1-30 (controlo de acesso): registe papéis de cliente com capabilities mínimas, protegidos por uma verificação de versão. Coloque os hooks de limpeza do menu num must-use-plugin para esconder opções sem uso a quem não é administrador. Use map_meta_cap para impedir que papéis restritos editem ou apaguem páginas-chave (por exemplo, a página inicial ou a de contacto).
  • Dias 31-60 (painel e definições): crie widgets do painel que mostrem o estado real e ligações de suporte. Use a Settings API para uma página de definições própria com validação e abra o grupo de opções ao papel do cliente com o filtro de capability. Acrescente atalhos na barra de ferramentas protegidos por nonce.
  • Dias 61-90 (marca e início de sessão): carregue os estilos do admin através de admin_enqueue_scripts, registe um esquema de cores e aplique a marca ao ecrã de início de sessão. Termine com a lista de entrega acima, testada com cada papel de cliente.

#O que lembrar na personalização do admin WordPress

Personalizar a área de admin não é apenas vaidade. É sobre experiência do utilizador e controlo de acesso. Carregue recursos com admin_enqueue_scripts, construa e limpe menus em admin_menu, verifique capabilities antes de esconder ou bloquear, isole o código num must-use-plugin e mantenha o CSS e o JS longe dos ecrãs do núcleo que não são seus.

Um painel de administração limpo reduz pedidos de suporte pela razão mais simples: o cliente deixa de ver opções que nunca deveria tocar. Fazemos essa personalização como parte do desenvolvimento de temas e plugins WordPress.

Próximo passo

Transforme o artigo numa implementação real

Este bloco reforça a ligação interna e conduz o leitor para o passo seguinte mais útil dentro da arquitetura do site.

Quer implementar isto no seu site?

Se quer transformar o artigo em melhorias concretas, redesign ou num plano de implementação, posso fechar o escopo e executar.

Cluster relacionado

Explorar outros serviços WordPress e base de conhecimento

Reforce o seu negócio com suporte técnico profissional em áreas-chave do ecossistema WordPress.

FAQ do artigo

Perguntas frequentes

Respostas práticas para aplicar o tema na execução real.

SEO-readyGEO-readyAEO-ready4 Q&A
O remove_menu_page bloqueia o acesso a uma página do admin?#
Não. Retira apenas o link do menu. Quem conhece o URL continua a entrar se o papel tiver a capability. O bloqueio real exige uma verificação de capability em current_screen ou admin_init, ou um papel sem essa capability.
Onde deve ficar o código de personalização do admin?#
Num must-use-plugin ou num plugin próprio da agência, não no tema. O tema muda num redesign, enquanto as regras de menu, os papéis e os widgets têm de continuar.
Como deixo um editor guardar uma página da Settings API?#
O wp-admin/options.php exige manage_options por omissão. O filtro option_page_capability_ seguido do nome do grupo de definições permite definir outra capability, como edit_pages, apenas para esse grupo.
Remover os widgets por omissão torna o painel mais rápido?#
Pouco. O widget de notícias guarda o resultado num transient e carrega-o por AJAX, e o widget de saúde do site lê um resultado guardado. O ganho é foco para o utilizador, não velocidade.

Precisa de FAQ adaptado ao setor e mercado? Criamos uma versão alinhada com os seus objetivos de negócio.

Fale connosco

Artigos Relacionados