I am working on a plugin to import content from a database into WordPress. What I am trying to do is have the processing done in an iframe so the output is displayed to the user like the plugins updater.

Let me explain my workflow to better understand my needs.

  • I first present a settings page to connect to an external database.
  • I then show a confirmation page with the connection details. If the connection was successful I give them options to select what to import and where to map it.

So far so good, everything works as expected.

  • Next I want them to click Import and the import process will complete through an iFrame outputting the data as it is being processed.

I currently have this last part working but I have some issues. First, it outputs data only when it is completed, not during the process. Second, I cannot use any WordPress hooks to modify the plugin as there are unique needs. This is where I am running into trouble. I call the iFrame directly in my plugin template file.

Plugin code:

add_action('mypluginimporter_import_iframe', array($this, 'displayImportIframe'));
function displayImportIframe() {
    // Display whatever it is you want to show
    echo '<iframe src="'.wp_nonce_url( PLUGIN_DIRECTORY_URL.'_processImport.php', 'mypluginimporter_import_iframe' ).'" width="100%" height="600px" frameBorder="0">Browser does not support iframes.</iframe>';

This is the view file:

<h3 style="margin: 0;"><?php _e('Import in Progress'); ?></h3>
<p class="description"><?php _e('This can take a long time depending on the size of the database.'); ?></p>
<p><?php _e('Import status will be outputted below.'); ?></p>
<?php do_action('mypluginimporter_import_iframe'); ?>

The _processImport.php file is:

// Loads the WordPress Environment
$tmpRootPath = dirname(dirname(dirname(dirname( __FILE__ ))));
if (file_exists($tmpRootPath . '/wp-blog-header.php')) {
    require_once( $tmpRootPath . '/wp-blog-header.php' );
} else {
    require_once( $tmpRootPath . '/wordpress/wp-blog-header.php' );

if (isset($_GET['_wpnonce']) && check_admin_referer( 'mypluginimporter_import_iframe')) {
    define( 'IFRAME_REQUEST', true );

    // Load the plugin
    require_once( dirname(__FILE__).'/MyPluginImporter.php' );


} else {
    die( _e('Invalid request') );

Now I know this is not the correct way to go about this. I am trying to find the best method to do this in WordPress. I also want to be able to use hooks and have other plugins hook into my plugin. I tried using the plugins_loaded hook but that didn't seem to do anything at all.

If more code or information is needed, I will provide as much as I can.

1 Answer 1


You could target admin-post.php to do the processing via the admin_post_$youraction hook:

This hook allows you to create custom handlers for your own custom GET and POST requests. The admin_post_ hook follows the format "admin_post_$youraction", where $youraction is your GET or POST request's 'action' parameter.

You can output the URL via admin_url( 'admin-post.php?action=add_foobar' ). Then hook your code:

add_action( 'admin_post_add_foobar', 'prefix_admin_add_foobar' );

function prefix_admin_add_foobar() {
    // Handle request then generate response using echo or leaving PHP and using HTML

If you want to update things as you go, then probably AJAX is what you want, which works similarly to the above, with an action parameter that maps to an action hook.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.