Posts tagged with: WordPress
← Back to all tagsA handy note for future-me or any other WordPress plugin developers:
If you need a plugin admin link that performs a download (e.g. a CSV file), you will need to use a hook that is called earlier in the process, before WP sends HTTP headers/content to the browser.
With a typical plugin admin page that displays content, I would use:
add_action( 'admin_menu', 'foo_add_menu' );
Then in function foo_add_menu()
, I would use add_menu_page like:
// my example is OO, so $this points to the object and calls the index() method add_menu_page( 'Plugin Page Title', 'Plugin Menu Title', 'edit_posts', $this->plugin_name . '_index', [$this, 'index'], '' );
If you try to do this with a method that starts a download, you will get errors like “Cannot modify header information.” This StackOverflow answer pointed me in the direction of the load-page hook to solve that.
That documentation is a bit slim, but what I figured out was add_menu_page()
returns a hook name. You can take that hook name, prefix “load-”, and use the resulting string as the hook name in an add_action()
.
In my example above, let’s say the plugin name is “foo_plugin” and replace “index” with “download”. The resulting hook name would be:
load-admin_page_foo_plugin_download
Then I can use:
add_action( 'load-admin_page_foo_plugin_download', 'download' );
(Be careful with the hyphen vs underscores in that)
Finally, within the download()
class method, I can safely modify HTTP headers to start a download:
header('Content-type: text/csv; charset=utf8'); // other headers and content...
Bookmarked: WordPress plugin boilerplate generator

Just making some small Wikipedia edits today.
(Not really, it’s just a browser preview 😂)