I’m constantly running into the same annoyance, so i thought i’d see if there’s any ideas or experience out there…
I’ve created a plugin that uses it’s own admin page. It has to. Now that i sorted out the WP_List_Table() stuff, i must say it’s great…but….
Custom plugin pages always load as admin.php?page=...
unless i want to load them from the plugin directory directly, which i don’t. Now if i do an ‘action’ from that page, i need to process that somehow and then redirect back to the page without the action parameter. No matter if i do a GET or POST, really.
On all it’s internal pages WP does this on the same page, it checks if there’s an action, if so processes it and then redirects to itself without the action. This is possible, because on these pages the admin-header
hasn’t been loaded, yet.
If you try doing it on your own page, though, half the admin interface has already been sent to the browser, so a redirect isn’t possible anymore. Clearly, the solution is to POST/GET directly to another page, load the WP framework on that, do the processing and then redirect back to the original page…but…that’s a bit annoying, because…my original page is loaded via a callback, so it runs within a method of my class. That’s beautiful.
If i load a separate page, i have to manually include wp-load.php
and am outside of my class, which is annoying, and in my particular case bugs me especially, because i’m only instanciating my plugin class anonymously so that no-one can access it from the outside.
So after this long story…did anyone come up with a good solution to load another page via a callback without having the whole admin interface already setup around it?
(I know of a workaround…i can hook a function into load-....
that checks for the action parameter and does the processing and redirect. But i’m wondering if there’s a better way.)
Thanks.
As a rule of thumb, you should use a POST request for most actions, to make sure they are not executed by accident. But it is also a good practice to redirect to a normal page after a POST request, to prevent duplicate execution when the user refreshes the page.
So the flow is like this:
The middle page doesn’t have to be your plugin page. This means that you can use the “generic POST handler” that was included three years ago, the
'admin_action_' . $_REQUEST['action']
hook inadmin.php
.An example user is the Akismet plugin. If you want to use it reliably, you have to submit to
admin.php
directly, not to another page that happens to includeadmin.php
.Here is a very basic example of how to use it:
I approached this slightly differently by simply adding noheader=true to the action url on the page where the user submits takes the action
My handler then performs the action (ie. typically an add, update or delete) then finisheswith a wp_redirect() to the next page action (e.g add page -> edit page, delete page -> list page, edit page -> edit page). I also pass a message on the URL so I can displayed a status such as update successfully or failed.
This approach keeps all the actions: list, add, edit, delete, bulk-delete, etc in the same class and with the same admin slug so it is pretty easy to maintain and to understand.
Another different approach is just adding a hidden input field to the form:
This way, WordPress seems to handle the redirect automatically.