Como impedir que os avisos tomem conta do painel do WordPress

Você abre o painel para corrigir um erro de digitação. Antes que você chegue à página, quatro mensagens passam na frente: um plugin de backup quer que você renove a licença, um plugin de formulários adoraria cinco estrelas, um plugin de SEO tem uma dica e um plugin de cache limpou o cache e achou que você devia saber. Depois de rolar a tela até passar por todas, o erro de digitação já pode esperar.
Os avisos são o jeito que o WordPress e os plugins encontraram para falar com você, e alguns têm mesmo algo a dizer: um backup que falhou, um plugin pausado depois de um erro fatal, uma licença que vence na sexta. O resto é marketing com a mesma borda colorida, no mesmo lugar, no topo de cada tela.
Por que os avisos se acumulam
O WordPress dispara um hook chamado admin_notices perto do topo de cada página do painel. Qualquer plugin pode exibir ali o que bem entender, e o WordPress usa o mesmo hook para as próprias mensagens, como o banner de atualização do core ou o alerta sobre plugins pausados pelo modo de recuperação. O WordPress não impõe limite nem ordem de importância.
O xizinho ajuda menos do que parece. Num aviso dispensável, o WordPress acrescenta um botão de fechar, e esse botão tira o aviso da página que está na sua frente. Lembrar do seu clique é trabalho do plugin. Muitos fazem isso. Os outros cumprimentam você de novo na tela seguinte, como se nada tivesse acontecido.
Duas soluções rápidas, ambas pouco sutis
A primeira é uma linha de CSS que esconde todos os .notice. A segunda é remove_all_actions( 'admin_notices' ), que simplesmente impede o WordPress de exibi-los.
As duas limpam o topo da tela. Também escondem o alerta sobre o backup que falhou ontem à noite, e você só descobre isso no dia em que precisa desse backup.
Mostre os avisos só para os administradores
Nos sites que você entrega, cabe um meio-termo justo: os administradores continuam vendo todos os avisos, e os demais não veem nenhum. Quem edita o site não tem o que fazer com um lembrete de licença e, de qualquer forma, não poderia agir sobre ele.
Salve este arquivo como wp-content/mu-plugins/quiet-admin-notices.php. O WordPress carrega os plugins must-use sozinho, e ninguém consegue desativá-los pela tela de Plugins, o que cai bem para uma regra da casa como esta.
<?php
/**
* Plugin Name: Quiet admin notices
* Description: Only administrators see admin notices.
*/
add_action( 'in_admin_header', function () {
if ( current_user_can( 'manage_options' ) ) {
return;
}
remove_all_actions( 'admin_notices' );
remove_all_actions( 'all_admin_notices' );
remove_all_actions( 'user_admin_notices' );
remove_all_actions( 'network_admin_notices' );
}, PHP_INT_MAX );
A função roda em in_admin_header, logo antes de o WordPress exibir os avisos e depois de todos os plugins terem acrescentado os seus. Os quatro hooks cobrem o painel normal, o painel do usuário e o painel da rede de um multisite. Um plugin que injeta o aviso via JavaScript ainda passa, porque nunca chegou perto do hook.
Remova um aviso que você conhece pelo nome
Às vezes é um aviso só que precisa sumir. Comece descobrindo quem o exibe. Este snippet grava no seu log de erros cada função ligada a admin_notices (wp-content/debug.log, com WP_DEBUG e WP_DEBUG_LOG ativados):
add_action( 'admin_notices', function () {
global $wp_filter;
foreach ( $wp_filter['admin_notices']->callbacks as $priority => $callbacks ) {
foreach ( $callbacks as $callback ) {
$f = $callback['function'];
if ( is_array( $f ) ) {
$class = is_object( $f[0] ) ? get_class( $f[0] ) : $f[0];
$name = $class . '::' . $f[1];
} elseif ( is_string( $f ) ) {
$name = $f;
} else {
$name = 'a closure';
}
error_log( "admin_notices, priority $priority: $name" );
}
}
}, PHP_INT_MIN );
Depois remova o aviso pelo nome, com a mesma prioridade com que ele foi adicionado. Errou a prioridade, e o remove_action() não faz nada, sem dar um pio.
add_action( 'in_admin_header', function () {
// A plain function, added with the default priority of 10.
remove_action( 'admin_notices', 'myplugin_renewal_notice' );
// A static method, added with priority 20.
remove_action( 'admin_notices', array( 'My_Plugin_Admin', 'review_request' ), 20 );
}, PHP_INT_MAX );
Você vai esbarrar em alguns limites. Um aviso adicionado pelo método de um objeto só pode ser removido com esse mesmo objeto, e os plugins raramente compartilham os seus. Um aviso adicionado por uma função anônima não pode ser removido de jeito nenhum. E quando o plugin renomeia a função numa atualização, o aviso volta e a sua lista precisa de mais uma linha.
Em vez disso, reúna os avisos
O problema dos avisos é o lugar onde eles ficam: no topo de cada tela, todos de uma vez, tenha você um minuto livre ou não. Coloque-os atrás de um contador. Você vê que tem algo esperando, abre a lista quando for melhor para você, e a página que você veio buscar volta para o topo. O retorno sobre algo que você acabou de fazer é outro caso: você clicou em Salvar, então «Configurações salvas» deve continuar aparecendo na hora.
A central de avisos do Refined Admin Dashboard
O Refined Admin Dashboard, nosso plugin gratuito que redesenha o painel inteiro do WordPress, trata os avisos desse jeito, sem nenhuma configuração para procurar. Nenhum aviso é maltratado durante o processo.
- Os avisos do WordPress e dos seus plugins vão para um contador de Notificações no canto superior direito da página, inclusive os que um plugin acrescenta depois via JavaScript.
- O plugin move cada aviso, sem nunca copiar nem apagar nenhum. Cada aviso mantém o próprio botão de fechar, então um plugin que lembra do seu clique continua lembrando.
- Descartar tudo aperta por você o botão de fechar de cada aviso. Um aviso sem botão de fechar fica na lista até que o plugin dele o retire.
- O retorno sobre o que você acabou de fazer, como «Configurações salvas» ou um erro de formulário, também aparece numa mensagem curta que some sozinha.
- Os avisos feitos para ficar dentro de um formulário continuam lá.
Um recado para quem desenvolve plugins
Se você desenvolve plugins, exiba seus avisos com wp_admin_notice() (WordPress 6.4 ou mais recente) em vez de marcação escrita à mão. Dê a cada um o tipo real (error, warning, success ou info), torne-o dispensável e lembre quando alguém o dispensar. Mantenha-o nas suas próprias telas, a menos que o site inteiro precise saber. E, por favor, deixe o banner de promoção fora da lista de posts. Seus usuários abriram aquela tela para escrever um post.
Perguntas frequentes
- Como esconder os avisos do painel do WordPress sem plugin?
- Crie um plugin must-use que chame remove_all_actions() em admin_notices a partir do hook in_admin_header. Limite isso às funções que não podem fazer nada com os avisos, para que os administradores continuem vendo um backup que falhou ou um plugin pausado. O código está neste artigo.
- É seguro esconder todos os avisos do painel?
- Não totalmente. Erros e marketing passam pelo mesmo hook, então você esconde um backup que falhou ou uma licença prestes a vencer junto com os banners de promoção. Esconda os avisos para as funções que não podem fazer nada com eles, ou reúna todos num só lugar.
- Por que os avisos do painel voltam depois de fechados?
- O botão de fechar que o WordPress acrescenta tira o aviso da página em que você está, e só. Quem precisa lembrar do seu clique é o plugin que exibiu o aviso, e alguns não lembram.
- Como mostrar os avisos do painel só para os administradores?
- Ligue ao hook in_admin_header uma função que retorna logo de cara para os usuários com a capacidade manage_options e, para os demais, chama remove_all_actions() em admin_notices, all_admin_notices, user_admin_notices e network_admin_notices. O snippet completo está neste artigo.
- O Refined Admin Dashboard apaga os avisos do painel?
- Não. Ele move cada aviso para um contador de Notificações que você abre quando quiser, e cada aviso mantém o próprio botão de fechar.