Como lidar melhor com as ações personalizadas da página de plug-in?

21

Estou constantemente correndo para o mesmo aborrecimento, então pensei em ver se há alguma idéia ou experiência por aí ...

Eu criei um plugin que usa sua própria página de administrador. Tem que ser. Agora que resolvi o material WP_List_Table (), devo dizer que é ótimo ... mas ....

As páginas personalizadas do plug-in sempre carregam como, a admin.php?page=...menos que eu queira carregá-las diretamente do diretório do plug-in, o que não acontece. Agora, se eu fizer uma 'ação' a ​​partir dessa página, preciso processar isso de alguma forma e depois redirecionar de volta para a página sem o parâmetro action. Não importa se eu faço um GET ou POST, realmente.

Em todas as suas páginas internas, o WP faz isso na mesma página, verifica se há uma ação; nesse caso, processa-a e depois redireciona para si mesma sem a ação. Isso é possível, porque nessas páginas o arquivo admin-headerainda não foi carregado.

Se você tentar fazer isso em sua própria página, metade da interface administrativa já foi enviada ao navegador, portanto, um redirecionamento não é mais possível. Claramente, a solução é POST / GET diretamente para outra página, carregar a estrutura WP, fazer o processamento e redirecionar de volta para a página original ... mas ... isso é um pouco chato, porque ... meu original A página é carregada por meio de um retorno de chamada, portanto, é executada dentro de um método da minha classe. Isso é bonito.

Se eu carregar uma página separada, tenho que incluir manualmente wp-load.phpe estar fora da minha classe, o que é irritante e, no meu caso particular, me incomoda especialmente, porque estou instanciando minha classe de plug-in anonimamente para que ninguém possa acessá-la. de fora.

Então, depois dessa longa história ... alguém encontrou uma boa solução para carregar outra página por meio de um retorno de chamada sem ter toda a interface administrativa já configurada?

(Eu sei de uma solução alternativa ... eu posso conectar uma função load-....que verifica o parâmetro de ação e faz o processamento e o redirecionamento. Mas estou me perguntando se existe uma maneira melhor.)

Obrigado.

Wyrfel
fonte
Por que isso está marcado [plugin-wp-pagenavi]? [plugin-development]é certamente bem-vindo aqui.
Jan Fabry
@ Fabry Jan: Não sei o que plugin-wp-pagenavié para ... eu estava assumindo que era para coisas relativas à correlação entre plugins e menu de administração. Como minha pergunta está relacionada a isso, eu selecionei essa tag.
28411 wyrfel
O WP-PageNavi é um plug-in com uma navegação de paginação mais avançada para o front-end. Você poderia usar [admin-menu]aqui, mas não acho que esteja relacionado a isso. Mudei as tags para o que eu acho adequado, é claro que você pode editá-lo novamente.
Jan Fabry
@ Jan Fabry: Obrigado pela remarcação ... ainda não familiarizado com todo o conjunto de marcações (obviamente).
Wyrfel #

Respostas:

28

Como regra geral, você deve usar uma solicitação POST para a maioria das ações, para garantir que elas não sejam executadas por acidente . Mas também é uma boa prática redirecionar para uma página normal após uma solicitação POST, para impedir a execução duplicada quando o usuário atualizar a página.

Portanto, o fluxo é assim:

  1. Sua página de plug-in com um formulário POST, que é enviado para
  2. Uma página que lida com a solicitação, que redireciona para
  3. Sua página de plug-in, que mostra o resultado da ação

A página do meio não precisa ser sua página de plug-in. Isso significa que você pode usar o "manipulador POST genérico" incluído há três anos, o 'admin_action_' . $_REQUEST['action']ganchoadmin.php .

Um usuário de exemplo é o plug-in Akismet . Se você quiser usá-lo de forma confiável, precisará enviar admin.phpdiretamente , não para outra página que incluaadmin.php .

Aqui está um exemplo muito básico de como usá-lo:

add_action( 'admin_action_wpse10500', 'wpse10500_admin_action' );
function wpse10500_admin_action()
{
    // Do your stuff here

    wp_redirect( $_SERVER['HTTP_REFERER'] );
    exit();
}

add_action( 'admin_menu', 'wpse10500_admin_menu' );
function wpse10500_admin_menu()
{
    add_management_page( 'WPSE 10500 Test page', 'WPSE 10500 Test page', 'administrator', 'wpse10500', 'wpse10500_do_page' );
}

function wpse10500_do_page()
{
?>
<form method="POST" action="<?php echo admin_url( 'admin.php' ); ?>">
    <input type="hidden" name="action" value="wpse10500" />
    <input type="submit" value="Do it!" />
</form>
<?php
}
Jan Fabry
fonte
Olá, vou olhar o código novamente, obviamente não vi isso, mas apenas para confirmar ... então o que você está dizendo é que, se eu chamar admin.php diretamente sem um parâmetro de página, ele pula toda a página carregando e apenas faz alguma inicialização e roda o gancho? Isso seria incrível ... ish (eu ainda não entendo por que eles não colocaram o gancho antes do carregamento da página).
27411 wyrfel
@wyrfel: Sim, ligar admin.phpdiretamente é o "truque" que a fonte do Akismet me ensinou. Você está certo quando está exibindo um formulário e deseja exibi-lo novamente em caso de erros: seria fácil se o destino for a página do plug-in, mas o gancho em algum lugar no início (para que você possa redirecionar se for bem-sucedido ou exibir o novamente com mensagens de erro). Talvez o sugira em um bilhete Trac?
Jan Fabry
Vou registrar um ticket. Como alternativa, achei o 'load-<pagehook>'gancho para funcionar ... ele é chamado antes que a página seja carregada ... mas o admin_action_...conceito parece muito mais agradável e mais específico. Além disso, em uma nota, as mensagens de erro ainda são problemáticas se você faz POSTs e não deseja repassar a atualização, mas esse é um tópico diferente.
Wyrfel 01/03
@wyrfel: Por que as mensagens de erro ainda seriam problemáticas? Se houver uma mensagem de erro, permaneça na página e exiba o formulário novamente com as mensagens (é claro que uma atualização não faria muito sentido aqui - mas também não faria mal, porque os erros ainda estariam lá e nenhuma ação será ser executado). Se não houver erros, execute a ação e redirecione para uma página de visão geral "segura". Isso funcionaria - se o admin_action_gancho fosse movido antes do carregador de páginas do plug-in.
Jan Fabry
Ok ... eu estava pensando muito complicado.
Wyrfel #
3

Abordei isso de maneira um pouco diferente, simplesmente adicionando noheader = true ao URL da ação na página em que o usuário envia a ação

Meu manipulador executa a ação (ou seja, normalmente adiciona, atualiza ou exclui) e termina com wp_redirect () para a próxima ação da página (por exemplo, adicionar página -> editar página, excluir página -> página de lista, editar página -> editar página ) Também passo uma mensagem no URL para que eu possa exibir um status como atualização com êxito ou falha.

Essa abordagem mantém todas as ações: listar, adicionar, editar, excluir, excluir em massa, etc. na mesma classe e com a mesma lesma de administrador, por isso é muito fácil de manter e entender.

Russell Jamieson
fonte
Cara, você é um gênio! Estou lutando há dois dias seguidos e parece que tudo que eu precisava era da parte "noheader = true". Obrigado!
R00m
0

Outra abordagem diferente é apenas adicionar um campo de entrada oculto ao formulário:

<input type="hidden" name="page" value="your-page-slug" />

Dessa forma, o WordPress parece manipular o redirecionamento automaticamente.

simonthesorcerer
fonte