diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css
index 705e64d942..9f873bd1d0 100644
--- a/src/wp-admin/css/common.css
+++ b/src/wp-admin/css/common.css
@@ -2275,15 +2275,47 @@ body.iframe {
display: block;
}
-.importers td {
- padding-right: 14px;
-}
-
.importers {
font-size: 16px;
width: auto;
}
+.importers td {
+ padding-right: 14px;
+ line-height: 1.5em;
+}
+
+.importers .import-system {
+ max-width: 250px;
+}
+
+.importers td.desc {
+ max-width: 500px;
+}
+
+.importer-title,
+.importer-desc,
+.importer-action {
+ display: block;
+}
+
+.importer-title {
+ color: #000;
+ font-size: 14px;
+ font-weight: 400;
+ margin-bottom: .2em;
+}
+
+.importer-action {
+ line-height: 20px; /* Same as with .updating-message */
+ color: #ddd;
+ margin-bottom: 1em;
+}
+
+.not-installed-main-site .importer-action {
+ color: #555;
+}
+
#post-body #post-body-content #namediv h3, /* Back-compat for pre-4.4 */
#post-body #post-body-content #namediv h2 {
margin-top: 0;
diff --git a/src/wp-admin/import.php b/src/wp-admin/import.php
index 962db681a2..5183766230 100644
--- a/src/wp-admin/import.php
+++ b/src/wp-admin/import.php
@@ -30,10 +30,12 @@ get_current_screen()->set_help_sidebar(
'
' . __('Support Forums') . '
'
);
-if ( current_user_can( 'install_plugins' ) )
+if ( current_user_can( 'install_plugins' ) ) {
+ // List of popular importer plugins from the WordPress.org API.
$popular_importers = wp_get_popular_importers();
-else
- $popular_importers = array();
+} else {
+ $popular_importers = array();
+}
// Detect and redirect invalid importers like 'movabletype', which is registered as 'mt'
if ( ! empty( $_GET['invalid'] ) && isset( $popular_importers[ $_GET['invalid'] ] ) ) {
@@ -66,7 +68,7 @@ $parent_file = 'tools.php';
$pop_data ) {
continue;
if ( isset( $importers[ $pop_data['importer-id'] ] ) )
continue;
+
+ // Fill the array of registered (already installed) importers with data of the popular importers from the WordPress.org API.
$importers[ $pop_data['importer-id'] ] = array( $pop_data['name'], $pop_data['description'], 'install' => $pop_data['plugin-slug'] );
}
@@ -85,43 +89,106 @@ if ( empty( $importers ) ) {
?>
- $data) {
- $action = '';
+ $data ) {
+ $plugin_slug = $action = '';
+ $is_plugin_installed = false;
+
if ( isset( $data['install'] ) ) {
$plugin_slug = $data['install'];
+
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_slug ) ) {
- // Looks like Importer is installed, But not active
+ // Looks like an importer is installed, but not active.
$plugins = get_plugins( '/' . $plugin_slug );
- if ( !empty($plugins) ) {
- $keys = array_keys($plugins);
+ if ( ! empty( $plugins ) ) {
+ $keys = array_keys( $plugins );
$plugin_file = $plugin_slug . '/' . $keys[0];
- $action = '' . $data[0] . '';
+ $url = wp_nonce_url( add_query_arg( array(
+ 'action' => 'activate',
+ 'plugin' => $plugin_file,
+ 'from' => 'import',
+ ), admin_url( 'plugins.php' ) ), 'activate-plugin_' . $plugin_file );
+ $action = sprintf(
+ '%s',
+ esc_url( $url ),
+ /* translators: %s: Importer name */
+ esc_attr( sprintf( __( 'Run %s' ), $data[0] ) ),
+ __( 'Run Importer' )
+ );
+
+ $is_plugin_installed = true;
}
}
- if ( empty($action) ) {
+
+ if ( empty( $action ) ) {
if ( is_main_site() ) {
- $action = '' . $data[0] . '';
+ $url = wp_nonce_url( add_query_arg( array(
+ 'action' => 'install-plugin',
+ 'plugin' => $plugin_slug,
+ 'from' => 'import',
+ ), self_admin_url( 'update.php' ) ), 'install-plugin_' . $plugin_slug );
+ $action = sprintf(
+ '%5$s',
+ esc_url( $url ),
+ esc_attr( $plugin_slug ),
+ esc_attr( $data[0] ),
+ /* translators: %s: Importer name */
+ esc_attr( sprintf( __( 'Install %s' ), $data[0] ) ),
+ __( 'Install Now' )
+ );
} else {
- $action = $data[0];
- $data[1] = sprintf( __( 'This importer is not installed. Please install importers from the main site.' ), get_admin_url( $current_site->blog_id, 'import.php' ) );
+ $action = sprintf(
+ /* translators: URL to wp-admin/import.php */
+ __( 'This importer is not installed. Please install importers from the main site.' ),
+ get_admin_url( get_current_network_id(), 'import.php' )
+ );
}
}
} else {
- $action = "{$data[0]}";
+ $url = add_query_arg( array(
+ 'import' => $importer_id,
+ ), self_admin_url( 'admin.php' ) );
+ $action = sprintf(
+ '%3$s',
+ esc_url( $url ),
+ /* translators: %s: Importer name */
+ esc_attr( sprintf( __( 'Run %s' ), $data[0] ) ),
+ __( 'Run Importer' )
+ );
+
+ $is_plugin_installed = true;
+ }
+
+ if ( ! $is_plugin_installed && is_main_site() ) {
+ $url = add_query_arg( array(
+ 'tab' => 'plugin-information',
+ 'plugin' => $plugin_slug,
+ 'from' => 'import',
+ 'TB_iframe' => 'true',
+ 'width' => 600,
+ 'height' => 550,
+ ), network_admin_url( 'plugin-install.php' ) );
+ $action .= sprintf(
+ ' | %3$s',
+ esc_url( $url ),
+ /* translators: %s: Importer name */
+ esc_attr( sprintf( __( 'More information about %s' ), $data[0] ) ),
+ __( 'Details' )
+ );
}
echo "
-
- $action |
- {$data[1]} |
+
+
+ {$data[0]}
+ {$action}
+ |
+
+ {$data[1]}
+ |
";
}
-?>
-
+ ?>
get_locale(),
+ 'version' => $wp_version,
+ ), 'http://api.wordpress.org/core/importers/1.1/' );
$options = array( 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url() );
$response = wp_remote_get( $url, $options );
$popular_importers = json_decode( wp_remote_retrieve_body( $response ), true );
- if ( is_array( $popular_importers ) )
- set_site_transient( 'popular_importers_' . $locale, $popular_importers, 2 * DAY_IN_SECONDS );
- else
+ if ( is_array( $popular_importers ) ) {
+ set_site_transient( $cache_key, $popular_importers, 2 * DAY_IN_SECONDS );
+ } else {
$popular_importers = false;
+ }
}
if ( is_array( $popular_importers ) ) {
@@ -157,49 +162,49 @@ function wp_get_popular_importers() {
// slug => name, description, plugin slug, and register_importer() slug
'blogger' => array(
'name' => __( 'Blogger' ),
- 'description' => __( 'Install the Blogger importer to import posts, comments, and users from a Blogger blog.' ),
+ 'description' => __( 'Import posts, comments, and users from a Blogger blog.' ),
'plugin-slug' => 'blogger-importer',
'importer-id' => 'blogger',
),
'wpcat2tag' => array(
'name' => __( 'Categories and Tags Converter' ),
- 'description' => __( 'Install the category/tag converter to convert existing categories to tags or tags to categories, selectively.' ),
+ 'description' => __( 'Convert existing categories to tags or tags to categories, selectively.' ),
'plugin-slug' => 'wpcat2tag-importer',
'importer-id' => 'wp-cat2tag',
),
'livejournal' => array(
'name' => __( 'LiveJournal' ),
- 'description' => __( 'Install the LiveJournal importer to import posts from LiveJournal using their API.' ),
+ 'description' => __( 'Import posts from LiveJournal using their API.' ),
'plugin-slug' => 'livejournal-importer',
'importer-id' => 'livejournal',
),
'movabletype' => array(
'name' => __( 'Movable Type and TypePad' ),
- 'description' => __( 'Install the Movable Type importer to import posts and comments from a Movable Type or TypePad blog.' ),
+ 'description' => __( 'Import posts and comments from a Movable Type or TypePad blog.' ),
'plugin-slug' => 'movabletype-importer',
'importer-id' => 'mt',
),
'opml' => array(
'name' => __( 'Blogroll' ),
- 'description' => __( 'Install the blogroll importer to import links in OPML format.' ),
+ 'description' => __( 'Import links in OPML format.' ),
'plugin-slug' => 'opml-importer',
'importer-id' => 'opml',
),
'rss' => array(
'name' => __( 'RSS' ),
- 'description' => __( 'Install the RSS importer to import posts from an RSS feed.' ),
+ 'description' => __( 'Import posts from an RSS feed.' ),
'plugin-slug' => 'rss-importer',
'importer-id' => 'rss',
),
'tumblr' => array(
'name' => __( 'Tumblr' ),
- 'description' => __( 'Install the Tumblr importer to import posts & media from Tumblr using their API.' ),
+ 'description' => __( 'Import posts & media from Tumblr using their API.' ),
'plugin-slug' => 'tumblr-importer',
'importer-id' => 'tumblr',
),
'wordpress' => array(
'name' => 'WordPress',
- 'description' => __( 'Install the WordPress importer to import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.' ),
+ 'description' => __( 'Import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.' ),
'plugin-slug' => 'wordpress-importer',
'importer-id' => 'wordpress',
),
diff --git a/src/wp-admin/js/updates.js b/src/wp-admin/js/updates.js
index 24a8186a24..8107426a50 100644
--- a/src/wp-admin/js/updates.js
+++ b/src/wp-admin/js/updates.js
@@ -503,11 +503,11 @@
}, args );
if ( 'import' === pagenow ) {
- $message = $( 'a[href*="' + args.slug + '"]' );
- } else {
- $message.text( wp.updates.l10n.installing );
+ $message = $( '[data-slug="' + args.slug + '"]' );
}
+ $message.text( wp.updates.l10n.installing );
+
$message
.addClass( 'updating-message' )
.attr( 'aria-label', wp.updates.l10n.pluginInstallingLabel.replace( '%s', $message.data( 'name' ) ) );
@@ -625,11 +625,14 @@
message: wp.updates.l10n.importerInstalledMsg.replace( '%s', response.activateUrl + '&from=import' )
} );
- $( 'a[href*="' + response.slug + '"]' )
- .removeClass( 'thickbox open-plugin-details-modal updating-message' )
- .off( 'click' )
- .attr( 'href', response.activateUrl + '&from=import' )
- .attr( 'title', wp.updates.l10n.activateImporter );
+ $( '[data-slug="' + response.slug + '"]' )
+ .removeClass( 'install-now updating-message' )
+ .addClass( 'activate-now' )
+ .attr({
+ 'href': response.activateUrl + '&from=import',
+ 'aria-label': wp.updates.l10n.activateImporterLabel.replace( '%s', response.pluginName )
+ })
+ .text( wp.updates.l10n.activateImporter );
wp.a11y.speak( wp.updates.l10n.installedMsg, 'polite' );
@@ -649,7 +652,9 @@
* @param {string} response.errorMessage The error that occurred.
*/
wp.updates.installImporterError = function( response ) {
- var errorMessage = wp.updates.l10n.installFailed.replace( '%s', response.errorMessage );
+ var errorMessage = wp.updates.l10n.installFailed.replace( '%s', response.errorMessage ),
+ $installLink = $( '[data-slug="' + response.slug + '"]' ),
+ pluginName = $installLink.data( 'name' );
if ( ! wp.updates.isValidResponse( response, 'install' ) ) {
return;
@@ -665,7 +670,10 @@
message: errorMessage
} );
- $( 'a[href*="' + response.slug + '"]' ).removeClass( 'updating-message' );
+ $installLink
+ .removeClass( 'updating-message' )
+ .text( wp.updates.l10n.installNow )
+ .attr( 'aria-label', wp.updates.l10n.installNowLabel.replace( '%s', pluginName ) );
wp.a11y.speak( errorMessage, 'assertive' );
@@ -1765,6 +1773,44 @@
} );
} );
+ /**
+ * Click handler for importer plugins installs in the Import screen.
+ *
+ * @since 4.6.0
+ *
+ * @param {Event} event Event interface.
+ */
+ $document.on( 'click', '.importer-item .install-now', function( event ) {
+ var $button = $( event.target ),
+ pluginName = $( this ).data( 'name' );
+
+ event.preventDefault();
+
+ if ( $button.hasClass( 'updating-message' ) ) {
+ return;
+ }
+
+ if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
+ wp.updates.requestFilesystemCredentials( event );
+
+ $document.on( 'credential-modal-cancel', function() {
+
+ $button
+ .removeClass( 'updating-message' )
+ .text( wp.updates.l10n.installNow )
+ .attr( 'aria-label', wp.updates.l10n.installNowLabel.replace( '%s', pluginName ) );
+
+ wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
+ } );
+ }
+
+ wp.updates.installPlugin( {
+ slug: $button.data( 'slug' ),
+ success: wp.updates.installImporterSuccess,
+ error: wp.updates.installImporterError
+ } );
+ } );
+
/**
* Click handler for plugin deletions.
*
diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php
index 759d15876d..e078886bc5 100644
--- a/src/wp-includes/script-loader.php
+++ b/src/wp-includes/script-loader.php
@@ -607,13 +607,13 @@ function wp_default_scripts( &$scripts ) {
'update' => __( 'Update' ),
'updateNow' => __( 'Update Now' ),
'updateFailedShort' => __( 'Update Failed!' ),
- /* translators: Error string for a failed update */
+ /* translators: %s: Error string for a failed update */
'updateFailed' => __( 'Update Failed: %s' ),
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'updatingLabel' => __( 'Updating %s...' ), // No ellipsis.
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'updatedLabel' => __( '%s updated!' ),
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'updateFailedLabel' => __( '%s update failed' ),
/* translators: JavaScript accessible string */
'updatingMsg' => __( 'Updating... please wait.' ), // No ellipsis.
@@ -623,27 +623,29 @@ function wp_default_scripts( &$scripts ) {
'updateCancel' => __( 'Update canceled.' ),
'beforeunload' => __( 'Updates may not complete if you navigate away from this page.' ),
'installNow' => __( 'Install Now' ),
+ /* translators: %s: Plugin name */
+ 'installNowLabel' => __( 'Install %s' ),
'installing' => __( 'Installing...' ),
'installed' => __( 'Installed!' ),
'installFailedShort' => __( 'Install Failed!' ),
- /* translators: Error string for a failed installation */
+ /* translators: %s: Error string for a failed installation */
'installFailed' => __( 'Installation failed: %s' ),
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'pluginInstallingLabel' => _x( 'Installing %s...', 'plugin' ), // no ellipsis
- /* translators: Theme name and version */
+ /* translators: %s: Theme name and version */
'themeInstallingLabel' => _x( 'Installing %s...', 'theme' ), // no ellipsis
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'pluginInstalledLabel' => _x( '%s installed!', 'plugin' ),
- /* translators: Theme name and version */
+ /* translators: %s: Theme name and version */
'themeInstalledLabel' => _x( '%s installed!', 'theme' ),
- /* translators: Plugin name and version */
+ /* translators: %s: Plugin name and version */
'pluginInstallFailedLabel' => _x( '%s installation failed', 'plugin' ),
- /* translators: Theme name and version */
+ /* translators: %s: Theme name and version */
'themeInstallFailedLabel' => _x( '%s installation failed', 'theme' ),
'installingMsg' => __( 'Installing... please wait.' ),
'installedMsg' => __( 'Installation completed successfully.' ),
- /* translators: Activation URL */
- 'importerInstalledMsg' => __( 'Importer installed successfully. Activate plugin & run importer' ),
+ /* translators: %s: Activation URL */
+ 'importerInstalledMsg' => __( 'Importer installed successfully. Run importer' ),
/* translators: %s: Theme name */
'aysDelete' => __( 'Are you sure you want to delete %s?' ),
/* translators: %s: Plugin name */
@@ -661,7 +663,9 @@ function wp_default_scripts( &$scripts ) {
'activatePluginLabel' => is_network_admin() ? _x( 'Network Activate %s', 'plugin' ) : _x( 'Activate %s', 'plugin' ),
/* translators: %s: Theme name */
'activateThemeLabel' => is_network_admin() ? _x( 'Network Activate %s', 'theme' ) : _x( 'Activate %s', 'theme' ),
- 'activateImporter' => __( 'Activate importer' ),
+ 'activateImporter' => __( 'Run Importer' ),
+ /* translators: %s: Importer name */
+ 'activateImporterLabel' => __( 'Run %s' ),
'unknownError' => __( 'An unknown error occurred' ),
'pluginsFound' => __( 'Number of plugins found: %d' ),
'noPluginsFound' => __( 'No plugins found. Try a different search.' ),
diff --git a/tests/qunit/fixtures/updates.js b/tests/qunit/fixtures/updates.js
index 8332039713..82a8311d60 100644
--- a/tests/qunit/fixtures/updates.js
+++ b/tests/qunit/fixtures/updates.js
@@ -30,7 +30,7 @@ window._wpUpdatesSettings = {
'themeInstallFailedLabel': '%s installation failed',
'installingMsg': 'Installing... please wait.',
'installedMsg': 'Installation completed successfully.',
- 'importerInstalledMsg': 'Importer installed successfully. Activate plugin & run importer',
+ 'importerInstalledMsg': 'Importer installed successfully. Run importer',
'aysDelete': 'Are you sure you want to delete %s?',
'aysDeleteUninstall': 'Are you sure you want to delete %s and its data?',
'aysBulkDelete': 'Are you sure you want to delete the selected plugins and their data?',
@@ -43,7 +43,7 @@ window._wpUpdatesSettings = {
'activateTheme': 'Activate',
'activatePluginLabel': 'Activate %s',
'activateThemeLabel': 'Activate %s',
- 'activateImporter': 'Activate importer',
+ 'activateImporter': 'Run Importer',
'unknownError': 'An unknown error occurred',
'pluginsFound': 'Number of plugins found: %d',
'noPluginsFound': 'No plugins found. Try a different search.'