Comment gérer au mieux les actions de page de plug-in personnalisées?

21

Je rencontre constamment la même contrariété, alors j'ai pensé voir s'il y avait des idées ou des expériences là-bas ...

J'ai créé un plugin qui utilise sa propre page d'administration. Il le faut. Maintenant que j'ai trié les trucs WP_List_Table (), je dois dire que c'est génial ... mais ....

Les pages de plugins personnalisées se chargent toujours comme, admin.php?page=...sauf si je veux les charger directement depuis le répertoire des plugins, ce que je ne fais pas. Maintenant, si je fais une «action» à partir de cette page, je dois traiter cela d'une manière ou d'une autre, puis rediriger vers la page sans le paramètre d'action. Peu importe si je fais un GET ou un POST, vraiment.

Sur toutes ses pages internes, WP le fait sur la même page, il vérifie s'il y a une action, si c'est le cas, puis la redirige vers lui-même sans l'action. C'est possible, car sur ces pages le admin-headern'a pas encore été chargé.

Si vous essayez de le faire sur votre propre page, cependant, la moitié de l'interface d'administration a déjà été envoyée au navigateur, donc une redirection n'est plus possible. De toute évidence, la solution consiste à POST / GET directement sur une autre page, à charger le cadre WP sur celui-ci, à effectuer le traitement, puis à rediriger vers la page d'origine ... mais ... c'est un peu ennuyeux, car ... mon original La page est chargée via un rappel, elle s'exécute donc dans une méthode de ma classe. C'est beau.

Si je charge une page séparée, je dois inclure manuellement wp-load.phpet être en dehors de ma classe, ce qui est ennuyeux, et dans mon cas particulier, cela me dérange particulièrement, car je ne fais qu'instancier ma classe de plug-in de manière anonyme afin que personne ne puisse y accéder de l'exterieur.

Donc, après cette longue histoire ... quelqu'un a-t-il trouvé une bonne solution pour charger une autre page via un rappel sans que toute l'interface d'administration soit déjà configurée autour d'elle?

(Je connais une solution de contournement ... je peux accrocher une fonction load-....qui vérifie le paramètre d'action et fait le traitement et la redirection. Mais je me demande s'il y a une meilleure façon.)

Merci.

wyrfel
la source
Pourquoi est-ce étiqueté avec [plugin-wp-pagenavi]? [plugin-development]est certainement la bienvenue ici.
Jan Fabry
@Jan Fabry: Je ne sais pas à quoi plugin-wp-pagenaviça sert ... je supposais que c'était pour des choses concernant la corrélation entre les plugins et le menu admin. Étant donné que ma question est liée à cela, j'ai sélectionné cette balise.
wyrfel
WP-PageNavi est un plugin avec une navigation de pagination plus avancée pour le front-end. Vous pouvez l'utiliser [admin-menu]ici, mais je ne pense pas que ce soit vraiment lié à cela. J'ai changé les balises pour qu'elles correspondent à ce que je pense, vous pouvez bien sûr les modifier à nouveau.
Jan Fabry
@Jan Fabry: Merci pour le re-tagging ... pas encore familier avec le pool de tags entier (bien évidemment).
wyrfel

Réponses:

28

En règle générale, vous devez utiliser une demande POST pour la plupart des actions, pour vous assurer qu'elles ne sont pas exécutées par accident . Mais il est également recommandé de rediriger vers une page normale après une demande POST, pour éviter l'exécution en double lorsque l'utilisateur actualise la page.

Donc, le flux est comme ceci:

  1. Votre page de plugin avec un formulaire POST, qui se soumet à
  2. Une page qui gère la demande, qui redirige vers
  3. Votre page de plugin, qui montre le résultat de l'action

La page du milieu n'a pas besoin d'être votre page de plugin. Cela signifie que vous pouvez utiliser le "gestionnaire POST générique" qui était inclus il y a trois ans, le 'admin_action_' . $_REQUEST['action']hookadmin.php .

Un exemple d'utilisateur est le plugin Akismet . Si vous souhaitez l'utiliser de manière fiable, vous devez vous soumettre admin.phpdirectement , et non à une autre page qui se trouve inclure admin.php.

Voici un exemple très simple de son utilisation:

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
la source
Hei, je vais regarder à nouveau le code, je n'ai évidemment pas vu ça, mais juste pour confirmer ... donc ce que vous dites, c'est que si j'appelle admin.php directement sans paramètre de page, il saute toutes les pages chargement et fait juste une certaine initialisation et exécute le crochet? Ce serait génial ... ish (je ne comprends toujours pas pourquoi ils n'ont pas mis le crochet avant le chargement de la page).
wyrfel
@wyrfel: Oui, appeler admin.phpdirectement est le "truc" que la source Akismet m'a appris. Vous avez raison lorsque vous affichez un formulaire et que vous souhaitez l'afficher à nouveau en cas d'erreur: alors ce serait facile si la destination est votre page de plugin mais le crochet quelque part au début (afin que vous puissiez rediriger en cas de succès, ou afficher le former à nouveau avec des messages d'erreur sinon). Peut-être le suggérer dans un ticket Trac?
Jan Fabry
Je déposerai un ticket. Pour contourner le problème, j'ai trouvé que le 'load-<pagehook>'crochet fonctionnait ... il est appelé avant le chargement de la page ... mais le admin_action_...concept semble beaucoup plus agréable et plus spécifique. En outre, sur une note, les messages d'erreur sont toujours problématiques si vous effectuez des POST et ne souhaitez pas republier lors du rechargement, mais c'est un sujet différent.
wyrfel
@wyrfel: Pourquoi les messages d'erreur seraient-ils toujours problématiques? S'il y a un message d'erreur, restez sur la page et affichez à nouveau le formulaire avec les messages (bien sûr, un rafraîchissement n'aurait pas beaucoup de sens ici - mais cela ne ferait pas de mal non plus, car les erreurs seraient toujours là et aucune action ne serait être exécuté). S'il n'y a aucune erreur, exécutez l'action et redirigez vers une page de présentation "sûre". Cela fonctionnerait - si le admin_action_crochet était déplacé avant le chargeur de page du plugin.
Jan Fabry
Ok ... je pensais trop compliqué.
wyrfel
3

J'ai abordé cela légèrement différemment en ajoutant simplement noheader = true à l'url d'action sur la page où l'utilisateur soumet prend l'action

Mon gestionnaire effectue ensuite l'action (c.-à-d. Généralement un ajout, une mise à jour ou une suppression) puis termine avec un wp_redirect () à l'action de la page suivante (par exemple, ajouter une page -> modifier la page, supprimer la page -> liste, modifier la page -> modifier la page ). Je passe également un message sur l'URL afin que je puisse afficher un état tel que la mise à jour réussie ou échouée.

Cette approche conserve toutes les actions: lister, ajouter, éditer, supprimer, supprimer en bloc, etc. dans la même classe et avec le même slug administrateur, il est donc assez facile à maintenir et à comprendre.

Russell Jamieson
la source
Mec, tu es génial! Je me bats depuis deux jours d'affilée et il semble que tout ce dont j'avais besoin était la partie "noheader = true". Merci!
r00m
0

Une autre approche différente consiste simplement à ajouter un champ de saisie masqué au formulaire:

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

De cette façon, WordPress semble gérer automatiquement la redirection.

simonthesorcerer
la source