Come posso gestire al meglio le azioni della pagina del plug-in personalizzato?


21

Mi imbatto costantemente nello stesso fastidio, quindi ho pensato di vedere se ci fossero idee o esperienze là fuori ...

Ho creato un plug-in che utilizza la propria pagina di amministrazione. Deve. Ora che ho risolto le cose di WP_List_Table (), devo dire che è fantastico ... ma ...

Le pagine del plug-in personalizzato vengono sempre caricate come admin.php?page=...se non desidero caricarle direttamente dalla directory del plug-in, cosa che non accade. Ora, se eseguo un'azione da quella pagina, devo elaborarla in qualche modo e quindi reindirizzare alla pagina senza il parametro action. Non importa se faccio un GET o POST, davvero.

WP lo fa su tutte le sue pagine interne sulla stessa pagina, controlla se c'è un'azione, in tal caso la elabora e quindi reindirizza a se stessa senza l'azione. Questo è possibile, perché su queste pagine admin-headernon è stato ancora caricato.

Se provi a farlo sulla tua pagina, tuttavia, metà dell'interfaccia di amministrazione è già stata inviata al browser, quindi un reindirizzamento non è più possibile. Chiaramente, la soluzione è POST / GET direttamente su un'altra pagina, caricare il framework WP su quello, eseguire l'elaborazione e quindi reindirizzare alla pagina originale ... ma ... è un po 'fastidioso, perché ... il mio originale la pagina viene caricata tramite un callback, quindi viene eseguita con un metodo della mia classe. Questo è bello.

Se carico una pagina separata, devo includere manualmente wp-load.phpe sono al di fuori della mia classe, il che è fastidioso, e nel mio caso particolare mi dà un bug in particolare, perché sto solo istanziando la mia classe di plugin in modo anonimo in modo che nessuno possa accedervi da fuori.

Quindi, dopo questa lunga storia ... qualcuno ha trovato una buona soluzione per caricare un'altra pagina tramite un callback senza avere l'intera interfaccia di amministrazione già configurata attorno ad essa?

(Conosco una soluzione alternativa ... posso agganciare una funzione load-....che controlla il parametro action ed esegue l'elaborazione e il reindirizzamento. Ma mi chiedo se c'è un modo migliore.)

Grazie.


Perché questo è taggato con [plugin-wp-pagenavi]? [plugin-development]è sicuramente il benvenuto qui.
Jan Fabry,

@Jan Fabry: Non so a cosa serva plugin-wp-pagenavi... stavo supponendo che fosse per cose riguardanti la correlazione tra plugin e menu di amministrazione. Poiché la mia domanda è correlata a ciò, ho selezionato quel tag.
wyrfel,

WP-PageNavi è un plugin con una navigazione di paging più avanzata per il front-end. Puoi usarlo [admin-menu]qui, ma non credo sia davvero correlato a questo. Ho cambiato i tag in quello che ritengo adatto, ovviamente puoi modificarlo di nuovo.
Jan Fabry

@Jan Fabry: grazie per la ricodifica ... non così familiare con l'intero pool di tag, ma (ovviamente).
Wyrfel,

Risposte:


28

Come regola generale, è necessario utilizzare una richiesta POST per la maggior parte delle azioni, per assicurarsi che non vengano eseguite per errore . Ma è anche buona norma reindirizzare a una pagina normale dopo una richiesta POST, per impedire l'esecuzione duplicata quando l'utente aggiorna la pagina.

Quindi il flusso è così:

  1. La tua pagina di plugin con un modulo POST, che invia
  2. Una pagina che gestisce la richiesta, che reindirizza a
  3. La pagina del tuo plug-in, che mostra il risultato dell'azione

La pagina centrale non deve essere la pagina del tuo plugin. Ciò significa che è possibile utilizzare il "gestore POST generico" che è stato incluso tre anni fa, l' 'admin_action_' . $_REQUEST['action']hook inadmin.php .

Un utente di esempio è il plugin Akismet . Se si desidera utilizzarlo in modo affidabile, è necessario inviare admin.phpdirettamente , non a un'altra pagina che sembra includere admin.php.

Ecco un esempio molto semplice di come usarlo:

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
}

Ehi, guarderò di nuovo il codice, ovviamente non l'ho visto, ma solo per confermare ... quindi quello che stai dicendo è che se chiamo admin.php direttamente senza un parametro di pagina, salta tutta la pagina caricamento e solo un po 'di inizializzazione ed esegue l'hook? Sarebbe fantastico ... ish (ancora non capisco perché non hanno messo il gancio prima del caricamento della pagina).
wyrfel,

@wyrfel: Sì, chiamare admin.phpdirettamente è il "trucco" che la fonte Akismet mi ha insegnato. Hai ragione quando visualizzi un modulo e vuoi visualizzarlo di nuovo in caso di errori: sarebbe facile se la destinazione è la tua pagina del plugin ma l'hook da qualche parte all'inizio (in modo da poter reindirizzare in caso di successo o visualizzare il modulo di nuovo con messaggi di errore in caso contrario). Forse suggerirlo in un biglietto Trac?
Jan Fabry

Presenterò un biglietto. Per ovviare al problema, ho scoperto che l' 'load-<pagehook>'hook funziona ... viene chiamato prima che la pagina venga caricata ... ma il admin_action_...concetto sembra molto più bello e più specifico. Inoltre, in una nota, i messaggi di errore sono ancora problematici se si eseguono i POST e non si desidera ripubblicare al ricaricamento, ma questo è un argomento diverso.
Wyrfel,

@wyrfel: Perché i messaggi di errore dovrebbero essere ancora problematici? Se c'è un messaggio di errore, rimani sulla pagina e visualizza nuovamente il modulo con i messaggi (ovviamente un aggiornamento non avrebbe molto senso qui - ma non farebbe alcun danno, perché gli errori sarebbero ancora lì e nessuna azione sarà essere eseguito). Se non ci sono errori, eseguire l'azione e reindirizzare a una pagina di panoramica "sicura". Funzionerebbe - se l' admin_action_hook fosse spostato prima del caricatore di pagine del plugin.
Jan Fabry

Ok ... stavo pensando troppo complicato.
Wyrfel,

3

L'ho affrontato in modo leggermente diverso semplicemente aggiungendo noheader = true all'URL dell'azione nella pagina in cui l'utente invia intraprende l'azione

Il mio gestore quindi esegue l'azione (ad es. In genere un aggiungi, aggiorna o elimina) quindi termina con wp_redirect () all'azione della pagina successiva (ad es. Aggiungi pagina -> modifica pagina, elimina pagina -> elenco pagina, modifica pagina -> modifica pagina ). Ho anche passato un messaggio sull'URL in modo da poter visualizzare uno stato come l'aggiornamento corretto o non riuscito.

Questo approccio mantiene tutte le azioni: elenca, aggiungi, modifica, elimina, elimina in blocco, ecc. Nella stessa classe e con la stessa lumaca di amministrazione, quindi è abbastanza facile da mantenere e da capire.


Amico, sei un genio! Ho lottato per due giorni di fila e sembra che tutto ciò di cui avevo bisogno fosse la parte "noheader = true". Grazie!
r00m

0

Un altro approccio diverso è semplicemente l'aggiunta di un campo di input nascosto al modulo:

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

In questo modo, WordPress sembra gestire automaticamente il reindirizzamento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.