2007-05-25 09:16:21 +02:00
< ? php
2008-10-02 03:03:26 +02:00
/**
* WordPress Theme Administration API
*
* @ package WordPress
* @ subpackage Administration
*/
2007-05-25 09:16:21 +02:00
2009-03-05 20:15:56 +01:00
/**
* Remove a theme
*
* @ since 2.8 . 0
*
2018-03-04 22:58:30 +01:00
* @ global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass .
2015-05-29 04:06:31 +02:00
*
2018-03-04 23:07:29 +01:00
* @ param string $stylesheet Stylesheet of the theme to delete .
* @ param string $redirect Redirect to page when complete .
* @ return bool | null | WP_Error True on success , false if `$stylesheet` is empty , WP_Error on failure .
* Null if filesystem credentials are required to proceed .
2009-03-05 20:15:56 +01:00
*/
2017-12-01 00:11:00 +01:00
function delete_theme ( $stylesheet , $redirect = '' ) {
2009-03-05 20:15:56 +01:00
global $wp_filesystem ;
2017-12-01 00:11:00 +01:00
if ( empty ( $stylesheet ) ) {
2009-03-05 20:15:56 +01:00
return false ;
2017-12-01 00:11:00 +01:00
}
2009-03-05 20:15:56 +01:00
2016-07-27 19:11:56 +02:00
if ( empty ( $redirect ) ) {
2017-12-01 00:11:00 +01:00
$redirect = wp_nonce_url ( 'themes.php?action=delete&stylesheet=' . urlencode ( $stylesheet ), 'delete-theme_' . $stylesheet );
2016-07-27 19:11:56 +02:00
}
ob_start ();
$credentials = request_filesystem_credentials ( $redirect );
2017-12-01 00:11:00 +01:00
$data = ob_get_clean ();
2015-06-27 03:12:24 +02:00
2016-07-27 19:11:56 +02:00
if ( false === $credentials ) {
2017-12-01 00:11:00 +01:00
if ( ! empty ( $data ) ) {
include_once ( ABSPATH . 'wp-admin/admin-header.php' );
2009-03-05 20:15:56 +01:00
echo $data ;
2017-12-01 00:11:00 +01:00
include ( ABSPATH . 'wp-admin/admin-footer.php' );
2009-03-05 20:15:56 +01:00
exit ;
}
return ;
}
2016-07-27 19:11:56 +02:00
if ( ! WP_Filesystem ( $credentials ) ) {
ob_start ();
request_filesystem_credentials ( $redirect , '' , true ); // Failed to connect, Error and request again.
2015-06-27 03:12:24 +02:00
$data = ob_get_clean ();
2017-12-01 00:11:00 +01:00
if ( ! empty ( $data ) ) {
include_once ( ABSPATH . 'wp-admin/admin-header.php' );
2009-03-05 20:15:56 +01:00
echo $data ;
2017-12-01 00:11:00 +01:00
include ( ABSPATH . 'wp-admin/admin-footer.php' );
2009-03-05 20:15:56 +01:00
exit ;
}
return ;
}
2017-12-01 00:11:00 +01:00
if ( ! is_object ( $wp_filesystem ) ) {
return new WP_Error ( 'fs_unavailable' , __ ( 'Could not access filesystem.' ) );
}
2009-03-05 20:15:56 +01:00
2018-02-27 03:31:31 +01:00
if ( is_wp_error ( $wp_filesystem -> errors ) && $wp_filesystem -> errors -> has_errors () ) {
2017-12-01 00:11:00 +01:00
return new WP_Error ( 'fs_error' , __ ( 'Filesystem error.' ), $wp_filesystem -> errors );
}
2009-03-05 20:15:56 +01:00
2014-10-08 21:05:20 +02:00
// Get the base plugin folder.
2009-03-05 20:15:56 +01:00
$themes_dir = $wp_filesystem -> wp_themes_dir ();
2014-10-08 21:05:20 +02:00
if ( empty ( $themes_dir ) ) {
2016-07-17 15:29:29 +02:00
return new WP_Error ( 'fs_no_themes_dir' , __ ( 'Unable to locate WordPress theme directory.' ) );
2014-10-08 21:05:20 +02:00
}
2009-03-05 20:15:56 +01:00
$themes_dir = trailingslashit ( $themes_dir );
2017-12-01 00:11:00 +01:00
$theme_dir = trailingslashit ( $themes_dir . $stylesheet );
$deleted = $wp_filesystem -> delete ( $theme_dir , true );
2014-10-08 21:05:20 +02:00
if ( ! $deleted ) {
return new WP_Error ( 'could_not_remove_theme' , sprintf ( __ ( 'Could not fully remove the theme %s.' ), $stylesheet ) );
}
$theme_translations = wp_get_installed_translations ( 'themes' );
// Remove language files, silently.
if ( ! empty ( $theme_translations [ $stylesheet ] ) ) {
$translations = $theme_translations [ $stylesheet ];
foreach ( $translations as $translation => $data ) {
$wp_filesystem -> delete ( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.po' );
$wp_filesystem -> delete ( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.mo' );
2019-01-21 21:41:50 +01:00
$json_translation_files = glob ( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '-*.json' );
if ( $json_translation_files ) {
array_map ( array ( $wp_filesystem , 'delete' ), $json_translation_files );
}
2014-10-08 21:05:20 +02:00
}
}
2009-03-05 20:15:56 +01:00
2016-04-14 05:49:26 +02:00
// Remove the theme from allowed themes on the network.
if ( is_multisite () ) {
WP_Theme :: network_disable_theme ( $stylesheet );
}
2014-10-08 21:05:20 +02:00
// Force refresh of theme update information.
delete_site_transient ( 'update_themes' );
2009-03-05 20:15:56 +01:00
return true ;
}
2008-10-02 03:03:26 +02:00
/**
2009-11-13 23:40:40 +01:00
* Get the Page Templates available in this theme
2008-10-02 03:03:26 +02:00
*
2010-12-01 20:24:38 +01:00
* @ since 1.5 . 0
Posts, Post Types: Add support for post type templates.
WordPress has supported custom page templates for over 12 years, allowing developers to create various layouts for specific pages.
While this feature is very helpful, it has always been limited to the 'page' post type and not was not available to other post types.
By opening up the page template functionality to all post types, we continue to improve the template hierarchy's flexibility.
In addition to the `Template Name` file header, the post types supported by a template can be specified using `Template Post Type: post, foo, bar`.
When at least one template exists for a post type, the 'Post Attributes' meta box will be displayed in the back end, without the need to add post type support for `'page-attributes'`. 'Post Attributes' can be customized per post type using the `'attributes'` label when registering a post type.
Props johnbillion, Mte90, dipesh.kakadiya, swissspidy.
Fixes #18375.
Built from https://develop.svn.wordpress.org/trunk@38951
git-svn-id: http://core.svn.wordpress.org/trunk@38894 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-10-26 10:07:30 +02:00
* @ since 4.7 . 0 Added the `$post_type` parameter .
2008-10-02 03:03:26 +02:00
*
Posts, Post Types: Add support for post type templates.
WordPress has supported custom page templates for over 12 years, allowing developers to create various layouts for specific pages.
While this feature is very helpful, it has always been limited to the 'page' post type and not was not available to other post types.
By opening up the page template functionality to all post types, we continue to improve the template hierarchy's flexibility.
In addition to the `Template Name` file header, the post types supported by a template can be specified using `Template Post Type: post, foo, bar`.
When at least one template exists for a post type, the 'Post Attributes' meta box will be displayed in the back end, without the need to add post type support for `'page-attributes'`. 'Post Attributes' can be customized per post type using the `'attributes'` label when registering a post type.
Props johnbillion, Mte90, dipesh.kakadiya, swissspidy.
Fixes #18375.
Built from https://develop.svn.wordpress.org/trunk@38951
git-svn-id: http://core.svn.wordpress.org/trunk@38894 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-10-26 10:07:30 +02:00
* @ param WP_Post | null $post Optional . The post being edited , provided for context .
* @ param string $post_type Optional . Post type to get the templates for . Default 'page' .
2011-04-13 13:50:27 +02:00
* @ return array Key is the template name , value is the filename of the template
2008-10-02 03:03:26 +02:00
*/
Posts, Post Types: Add support for post type templates.
WordPress has supported custom page templates for over 12 years, allowing developers to create various layouts for specific pages.
While this feature is very helpful, it has always been limited to the 'page' post type and not was not available to other post types.
By opening up the page template functionality to all post types, we continue to improve the template hierarchy's flexibility.
In addition to the `Template Name` file header, the post types supported by a template can be specified using `Template Post Type: post, foo, bar`.
When at least one template exists for a post type, the 'Post Attributes' meta box will be displayed in the back end, without the need to add post type support for `'page-attributes'`. 'Post Attributes' can be customized per post type using the `'attributes'` label when registering a post type.
Props johnbillion, Mte90, dipesh.kakadiya, swissspidy.
Fixes #18375.
Built from https://develop.svn.wordpress.org/trunk@38951
git-svn-id: http://core.svn.wordpress.org/trunk@38894 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-10-26 10:07:30 +02:00
function get_page_templates ( $post = null , $post_type = 'page' ) {
return array_flip ( wp_get_theme () -> get_page_templates ( $post , $post_type ) );
2007-05-25 09:16:21 +02:00
}
2009-10-19 23:39:04 +02:00
/**
* Tidies a filename for url display by the theme editor .
2010-01-15 23:11:12 +01:00
*
2009-10-19 23:39:04 +02:00
* @ since 2.9 . 0
2010-05-03 15:27:15 +02:00
* @ access private
2010-01-15 23:11:12 +01:00
*
2009-10-19 23:39:04 +02:00
* @ param string $fullpath Full path to the theme file
* @ param string $containingfolder Path of the theme parent folder
* @ return string
*/
2017-12-01 00:11:00 +01:00
function _get_template_edit_filename ( $fullpath , $containingfolder ) {
return str_replace ( dirname ( dirname ( $containingfolder ) ), '' , $fullpath );
2009-10-19 23:39:04 +02:00
}
2010-05-03 15:29:15 +02:00
/**
* Check if there is an update for a theme available .
*
* Will display link , if there is an update available .
*
* @ since 2.7 . 0
2013-11-20 03:57:10 +01:00
* @ see get_theme_update_available ()
2010-05-03 15:29:15 +02:00
*
2015-05-29 22:17:26 +02:00
* @ param WP_Theme $theme Theme data object .
2010-05-03 15:29:15 +02:00
*/
function theme_update_available ( $theme ) {
2013-11-20 03:57:10 +01:00
echo get_theme_update_available ( $theme );
}
/**
2013-12-06 20:18:11 +01:00
* Retrieve the update link if there is a theme update available .
2013-11-20 03:57:10 +01:00
*
2013-12-06 20:18:11 +01:00
* Will return a link if there is an update available .
2013-11-20 03:57:10 +01:00
*
* @ since 3.8 . 0
*
2015-05-29 17:43:29 +02:00
* @ staticvar object $themes_update
*
2013-12-06 20:18:11 +01:00
* @ param WP_Theme $theme WP_Theme object .
2014-12-01 02:00:22 +01:00
* @ return false | string HTML for the update link , or false if invalid info was passed .
2013-11-20 03:57:10 +01:00
*/
function get_theme_update_available ( $theme ) {
2015-05-29 17:43:29 +02:00
static $themes_update = null ;
2010-05-03 15:29:15 +02:00
2017-12-01 00:11:00 +01:00
if ( ! current_user_can ( 'update_themes' ) ) {
2013-11-20 03:57:10 +01:00
return false ;
2017-12-01 00:11:00 +01:00
}
2010-05-03 15:29:15 +02:00
2017-12-01 00:11:00 +01:00
if ( ! isset ( $themes_update ) ) {
$themes_update = get_site_transient ( 'update_themes' );
}
2010-05-03 15:29:15 +02:00
2015-01-16 02:06:24 +01:00
if ( ! ( $theme instanceof WP_Theme ) ) {
2013-11-20 03:57:10 +01:00
return false ;
2015-01-16 02:06:24 +01:00
}
Introduce WP_Theme, wp_get_themes(), and wp_get_theme() to replace get_themes(), get_theme(), get_theme_data(), current_theme_info(), and others.
* Getters and Helpers: Introduces a series of methods to allow for easy generation of headers for display, and other theme metadata, including page templates.
* Screenshots: Handles support for multiple screenshots. (see # Additional screenshots must be PNG and start with screenshot-2.png, and be sequential to be counted. see #19816.
* Error Handling: Broken themes have a WP_Error object attached to them.
* Caching: Introduces a wp_cache_themes_persistently filter (also in [20020]) to enable persistent caching of all filesystem and sanitization operations normally handled by WP_Theme (and formerly get_file_data() and get_themes()). Themes are cached individually and across five different cache keys for different data pieces.
* Compatibility: A WP_Theme object is backwards compatible with a theme's array formerly returned by get_themes() and get_theme(), and an stdClass object formerly returned by current_theme_info().
* i18n/L10n: Theme headers are now localizable with proper Text Domain and Domain Path headers, like plugins. (Language packs may remove the requirement for headers.) For page templates, see #6007 (not fixed yet, but will be easy now). For headers, fixes #15858.
* PHP and CSS files: New methods that fetch a list of theme files (for the theme editor) only on demand, rather than only loading them into memory. fixes #11214.
Functions deprecated:
* get_themes(), get_allowed_themes() and get_broken_themes() -- use wp_get_themes()
* get_theme() and current_theme_info() -- use wp_get_theme()
* get_site_allowed_themes() -- use WP_Theme::get_allowed_on_network()
* wpmu_get_blog_allowedthemes() -- use WP_theme::get_allowed_on_site()
see also [20016], [20018], [20019], [20020], [20021], [20022], [20025], [20026], [20027]. also fixes #19244.
see #20103.
git-svn-id: http://svn.automattic.com/wordpress/trunk@20029 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-02-28 22:24:44 +01:00
$stylesheet = $theme -> get_stylesheet ();
2010-05-03 15:29:15 +02:00
2013-11-20 03:57:10 +01:00
$html = '' ;
2017-12-01 00:11:00 +01:00
if ( isset ( $themes_update -> response [ $stylesheet ] ) ) {
$update = $themes_update -> response [ $stylesheet ];
$theme_name = $theme -> display ( 'Name' );
$details_url = add_query_arg (
array (
'TB_iframe' => 'true' ,
'width' => 1024 ,
'height' => 800 ,
2018-08-17 03:51:36 +02:00
),
$update [ 'url' ]
2017-12-01 00:11:00 +01:00
); //Theme browser inside WP? replace this, Also, theme preview JS will override this on the available list.
$update_url = wp_nonce_url ( admin_url ( 'update.php?action=upgrade-theme&theme=' . urlencode ( $stylesheet ) ), 'upgrade-theme_' . $stylesheet );
if ( ! is_multisite () ) {
if ( ! current_user_can ( 'update_themes' ) ) {
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: theme details URL, 3: additional link attributes, 4: version number */
2017-12-01 00:11:00 +01:00
$html = sprintf (
'<p><strong>' . __ ( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ) . '</strong></p>' ,
2016-03-04 12:12:26 +01:00
$theme_name ,
esc_url ( $details_url ),
2017-12-01 00:11:00 +01:00
sprintf (
'class="thickbox open-plugin-details-modal" aria-label="%s"' ,
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: version number */
esc_attr ( sprintf ( __ ( 'View %1$s version %2$s details' ), $theme_name , $update [ 'new_version' ] ) )
),
2016-03-04 12:12:26 +01:00
$update [ 'new_version' ]
);
2015-01-08 08:05:25 +01:00
} elseif ( empty ( $update [ 'package' ] ) ) {
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: theme details URL, 3: additional link attributes, 4: version number */
2017-12-01 00:11:00 +01:00
$html = sprintf (
'<p><strong>' . __ ( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ) . '</strong></p>' ,
2016-03-04 12:12:26 +01:00
$theme_name ,
esc_url ( $details_url ),
2017-12-01 00:11:00 +01:00
sprintf (
'class="thickbox open-plugin-details-modal" aria-label="%s"' ,
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: version number */
esc_attr ( sprintf ( __ ( 'View %1$s version %2$s details' ), $theme_name , $update [ 'new_version' ] ) )
),
2016-03-04 12:12:26 +01:00
$update [ 'new_version' ]
);
2013-11-20 03:57:10 +01:00
} else {
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: theme details URL, 3: additional link attributes, 4: version number, 5: update URL, 6: additional link attributes */
2017-12-01 00:11:00 +01:00
$html = sprintf (
'<p><strong>' . __ ( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ) . '</strong></p>' ,
2016-03-04 12:12:26 +01:00
$theme_name ,
esc_url ( $details_url ),
2017-12-01 00:11:00 +01:00
sprintf (
'class="thickbox open-plugin-details-modal" aria-label="%s"' ,
2016-07-17 23:03:31 +02:00
/* translators: 1: theme name, 2: version number */
esc_attr ( sprintf ( __ ( 'View %1$s version %2$s details' ), $theme_name , $update [ 'new_version' ] ) )
),
2016-03-04 12:12:26 +01:00
$update [ 'new_version' ],
$update_url ,
2017-12-01 00:11:00 +01:00
sprintf (
'aria-label="%s" id="update-theme" data-slug="%s"' ,
2016-07-17 23:03:31 +02:00
/* translators: %s: theme name */
esc_attr ( sprintf ( __ ( 'Update %s now' ), $theme_name ) ),
$stylesheet
)
2016-03-04 12:12:26 +01:00
);
2013-11-20 03:57:10 +01:00
}
2010-11-30 04:03:40 +01:00
}
2010-05-03 15:29:15 +02:00
}
2013-11-20 03:57:10 +01:00
return $html ;
2010-05-03 15:29:15 +02:00
}
2010-09-24 17:28:28 +02:00
/**
2019-01-18 02:03:50 +01:00
* Retrieve list of WordPress theme features ( aka theme tags ) .
2010-09-24 17:28:28 +02:00
*
* @ since 3.1 . 0
*
2015-11-22 23:38:26 +01:00
* @ param bool $api Optional . Whether try to fetch tags from the WordPress . org API . Defaults to true .
2011-12-14 18:36:38 +01:00
* @ return array Array of features keyed by category with translations keyed by slug .
2010-09-24 17:28:28 +02:00
*/
2012-02-28 21:38:09 +01:00
function get_theme_feature_list ( $api = true ) {
2010-09-24 17:28:28 +02:00
// Hard-coded list is used if api not accessible.
$features = array (
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
__ ( 'Subject' ) => array (
'blog' => __ ( 'Blog' ),
'e-commerce' => __ ( 'E-Commerce' ),
'education' => __ ( 'Education' ),
'entertainment' => __ ( 'Entertainment' ),
'food-and-drink' => __ ( 'Food & Drink' ),
'holiday' => __ ( 'Holiday' ),
'news' => __ ( 'News' ),
'photography' => __ ( 'Photography' ),
'portfolio' => __ ( 'Portfolio' ),
2010-09-24 17:28:28 +02:00
),
__ ( 'Features' ) => array (
2013-12-05 04:49:10 +01:00
'accessibility-ready' => __ ( 'Accessibility Ready' ),
2011-06-22 21:45:21 +02:00
'custom-background' => __ ( 'Custom Background' ),
'custom-colors' => __ ( 'Custom Colors' ),
'custom-header' => __ ( 'Custom Header' ),
2016-07-04 11:35:27 +02:00
'custom-logo' => __ ( 'Custom Logo' ),
2011-06-22 21:45:21 +02:00
'editor-style' => __ ( 'Editor Style' ),
'featured-image-header' => __ ( 'Featured Image Header' ),
'featured-images' => __ ( 'Featured Images' ),
Themes: Update list of WordPress theme features.
* Remove color tags.
* Layout: Add Grid Layout, remove Fixed Layout, Fluid Layout, and Responsive Layout.
* Features: Add Footer Widgets, remove Blavatar.
* Subject: Add Blog, E-Commerce, Education, Entertainment, Food & Drink, Holiday, News, Photography and Portfolio, remove Photoblogging and Seasonal.
Props grapplerulrich, davewarfel.
Fixes #33407.
Built from https://develop.svn.wordpress.org/trunk@37287
git-svn-id: http://core.svn.wordpress.org/trunk@37253 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-04-21 23:11:29 +02:00
'footer-widgets' => __ ( 'Footer Widgets' ),
2011-06-22 21:45:21 +02:00
'full-width-template' => __ ( 'Full Width Template' ),
'post-formats' => __ ( 'Post Formats' ),
'sticky-post' => __ ( 'Sticky Post' ),
'theme-options' => __ ( 'Theme Options' ),
2010-09-24 17:28:28 +02:00
),
2017-12-01 00:11:00 +01:00
__ ( 'Layout' ) => array (
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
'grid-layout' => __ ( 'Grid Layout' ),
'one-column' => __ ( 'One Column' ),
'two-columns' => __ ( 'Two Columns' ),
'three-columns' => __ ( 'Three Columns' ),
'four-columns' => __ ( 'Four Columns' ),
'left-sidebar' => __ ( 'Left Sidebar' ),
'right-sidebar' => __ ( 'Right Sidebar' ),
2017-12-01 00:11:00 +01:00
),
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
2010-09-24 17:28:28 +02:00
);
2017-12-01 00:11:00 +01:00
if ( ! $api || ! current_user_can ( 'install_themes' ) ) {
2010-09-24 17:28:28 +02:00
return $features ;
2017-12-01 00:11:00 +01:00
}
2010-09-24 17:28:28 +02:00
2017-12-01 00:11:00 +01:00
if ( ! $feature_list = get_site_transient ( 'wporg_theme_feature_list' ) ) {
2014-05-05 10:26:24 +02:00
set_site_transient ( 'wporg_theme_feature_list' , array (), 3 * HOUR_IN_SECONDS );
2017-12-01 00:11:00 +01:00
}
2010-09-24 17:28:28 +02:00
2017-12-01 00:11:00 +01:00
if ( ! $feature_list ) {
2013-01-04 11:13:51 +01:00
$feature_list = themes_api ( 'feature_list' , array () );
2017-12-01 00:11:00 +01:00
if ( is_wp_error ( $feature_list ) ) {
2010-09-24 17:28:28 +02:00
return $features ;
2017-12-01 00:11:00 +01:00
}
2010-09-24 17:28:28 +02:00
}
2017-12-01 00:11:00 +01:00
if ( ! $feature_list ) {
2010-09-24 17:28:28 +02:00
return $features ;
2017-12-01 00:11:00 +01:00
}
2010-09-24 17:28:28 +02:00
2014-05-05 10:26:24 +02:00
set_site_transient ( 'wporg_theme_feature_list' , $feature_list , 3 * HOUR_IN_SECONDS );
2010-09-24 17:28:28 +02:00
2014-01-05 18:16:11 +01:00
$category_translations = array (
'Layout' => __ ( 'Layout' ),
'Features' => __ ( 'Features' ),
2016-07-04 12:01:28 +02:00
'Subject' => __ ( 'Subject' ),
2014-01-05 18:16:11 +01:00
);
2010-09-24 17:28:28 +02:00
// Loop over the wporg canonical list and apply translations
$wporg_features = array ();
foreach ( ( array ) $feature_list as $feature_category => $feature_items ) {
2017-12-01 00:11:00 +01:00
if ( isset ( $category_translations [ $feature_category ] ) ) {
$feature_category = $category_translations [ $feature_category ];
}
$wporg_features [ $feature_category ] = array ();
2010-09-24 17:28:28 +02:00
foreach ( $feature_items as $feature ) {
2017-12-01 00:11:00 +01:00
if ( isset ( $features [ $feature_category ][ $feature ] ) ) {
$wporg_features [ $feature_category ][ $feature ] = $features [ $feature_category ][ $feature ];
} else {
$wporg_features [ $feature_category ][ $feature ] = $feature ;
}
2010-09-24 17:28:28 +02:00
}
}
return $wporg_features ;
}
2010-10-05 15:24:41 +02:00
/**
2015-09-27 23:52:25 +02:00
* Retrieves theme installer pages from the WordPress . org Themes API .
2010-10-05 15:24:41 +02:00
*
* It is possible for a theme to override the Themes API result with three
2016-07-05 00:45:29 +02:00
* filters . Assume this is for themes , which can extend on the Theme Info to
2010-10-05 15:24:41 +02:00
* offer more choices . This is very powerful and must be used with care , when
2014-08-13 05:56:17 +02:00
* overriding the filters .
2010-10-05 15:24:41 +02:00
*
2015-09-27 23:52:25 +02:00
* The first filter , { @ see 'themes_api_args' }, is for the args and gives the action
* as the second parameter . The hook for { @ see 'themes_api_args' } must ensure that
* an object is returned .
2010-10-05 15:24:41 +02:00
*
2015-09-28 00:45:25 +02:00
* The second filter , { @ see 'themes_api' }, allows a plugin to override the WordPress . org
2015-09-28 00:47:25 +02:00
* Theme API entirely . If `$action` is 'query_themes' , 'theme_information' , or 'feature_list' ,
2016-07-09 16:39:33 +02:00
* an object MUST be passed . If `$action` is 'hot_tags' , an array should be passed .
2015-09-28 00:45:25 +02:00
*
* Finally , the third filter , { @ see 'themes_api_result' }, makes it possible to filter the
* response object or array , depending on the `$action` type .
2015-09-27 23:52:25 +02:00
*
* Supported arguments per action :
*
2015-09-28 00:47:25 +02:00
* | Argument Name | 'query_themes' | 'theme_information' | 'hot_tags' | 'feature_list' |
2015-09-28 00:49:24 +02:00
* | -------------------| :------------: | :-----------------: | :--------: | :--------------: |
* | `$slug` | No | Yes | No | No |
* | `$per_page` | Yes | No | No | No |
* | `$page` | Yes | No | No | No |
* | `$number` | No | No | Yes | No |
* | `$search` | Yes | No | No | No |
* | `$tag` | Yes | No | No | No |
* | `$author` | Yes | No | No | No |
* | `$user` | Yes | No | No | No |
* | `$browse` | Yes | No | No | No |
* | `$locale` | Yes | Yes | No | No |
* | `$fields` | Yes | Yes | No | No |
2010-10-05 15:24:41 +02:00
*
* @ since 2.8 . 0
*
2015-09-27 23:52:25 +02:00
* @ param string $action API action to perform : 'query_themes' , 'theme_information' ,
* 'hot_tags' or 'feature_list' .
* @ param array | object $args {
2016-09-19 18:46:30 +02:00
* Optional . Array or object of arguments to serialize for the Themes API .
2015-09-27 23:52:25 +02:00
*
2016-09-19 18:46:30 +02:00
* @ type string $slug The theme slug . Default empty .
2015-09-27 23:52:25 +02:00
* @ type int $per_page Number of themes per page . Default 24.
* @ type int $page Number of current page . Default 1.
* @ type int $number Number of tags to be queried .
* @ type string $search A search term . Default empty .
* @ type string $tag Tag to filter themes . Default empty .
* @ type string $author Username of an author to filter themes . Default empty .
* @ type string $user Username to query for their favorites . Default empty .
* @ type string $browse Browse view : 'featured' , 'popular' , 'updated' , 'favorites' .
* @ type string $locale Locale to provide context - sensitive results . Default is the value of get_locale () .
* @ type array $fields {
* Array of fields which should or should not be returned .
*
* @ type bool $description Whether to return the theme full description . Default false .
* @ type bool $sections Whether to return the theme readme sections : description , installation ,
* FAQ , screenshots , other notes , and changelog . Default false .
* @ type bool $rating Whether to return the rating in percent and total number of ratings .
* Default false .
* @ type bool $ratings Whether to return the number of rating for each star ( 1 - 5 ) . Default false .
* @ type bool $downloaded Whether to return the download count . Default false .
* @ type bool $downloadlink Whether to return the download link for the package . Default false .
* @ type bool $last_updated Whether to return the date of the last update . Default false .
* @ type bool $tags Whether to return the assigned tags . Default false .
* @ type bool $homepage Whether to return the theme homepage link . Default false .
* @ type bool $screenshots Whether to return the screenshots . Default false .
* @ type int $screenshot_count Number of screenshots to return . Default 1.
* @ type bool $screenshot_url Whether to return the URL of the first screenshot . Default false .
* @ type bool $photon_screenshots Whether to return the screenshots via Photon . Default false .
* @ type bool $template Whether to return the slug of the parent theme . Default false .
* @ type bool $parent Whether to return the slug , name and homepage of the parent theme . Default false .
* @ type bool $versions Whether to return the list of all available versions . Default false .
* @ type bool $theme_url Whether to return theme ' s URL . Default false .
* @ type bool $extended_author Whether to return nicename or nicename and display name . Default false .
* }
* }
* @ return object | array | WP_Error Response object or array on success , WP_Error on failure . See the
* { @ link https :// developer . wordpress . org / reference / functions / themes_api / function reference article }
* for more information on the make - up of possible return objects depending on the value of `$action` .
2010-10-05 15:24:41 +02:00
*/
2015-09-27 23:52:25 +02:00
function themes_api ( $action , $args = array () ) {
2018-02-01 06:19:30 +01:00
// include an unmodified $wp_version
include ( ABSPATH . WPINC . '/version.php' );
2010-10-05 15:24:41 +02:00
2014-12-16 23:39:22 +01:00
if ( is_array ( $args ) ) {
$args = ( object ) $args ;
}
2010-10-05 15:24:41 +02:00
2018-02-01 06:19:30 +01:00
if ( 'query_themes' == $action ) {
if ( ! isset ( $args -> per_page ) ) {
$args -> per_page = 24 ;
}
2014-12-16 23:39:22 +01:00
}
if ( ! isset ( $args -> locale ) ) {
2016-10-03 09:04:29 +02:00
$args -> locale = get_user_locale ();
2014-12-16 23:39:22 +01:00
}
2018-02-01 06:19:30 +01:00
if ( ! isset ( $args -> wp_version ) ) {
$args -> wp_version = substr ( $wp_version , 0 , 3 ); // X.y
}
2013-10-30 15:39:10 +01:00
/**
2016-05-22 20:01:30 +02:00
* Filters arguments used to query for installer pages from the WordPress . org Themes API .
2013-10-30 15:39:10 +01:00
*
* Important : An object MUST be returned to this filter .
2013-12-04 21:03:09 +01:00
*
2013-10-30 15:39:10 +01:00
* @ since 2.8 . 0
2013-12-04 21:03:09 +01:00
*
2013-10-30 15:39:10 +01:00
* @ param object $args Arguments used to query for installer pages from the WordPress . org Themes API .
* @ param string $action Requested action . Likely values are 'theme_information' ,
* 'feature_list' , or 'query_themes' .
2014-12-16 23:39:22 +01:00
*/
2013-10-30 15:39:10 +01:00
$args = apply_filters ( 'themes_api_args' , $args , $action );
2013-12-11 20:49:11 +01:00
2013-10-30 15:39:10 +01:00
/**
2016-05-22 20:01:30 +02:00
* Filters whether to override the WordPress . org Themes API .
2013-10-30 15:39:10 +01:00
*
2015-09-28 01:01:24 +02:00
* Passing a non - false value will effectively short - circuit the WordPress . org API request .
*
* If `$action` is 'query_themes' , 'theme_information' , or 'feature_list' , an object MUST
2016-07-09 16:39:33 +02:00
* be passed . If `$action` is 'hot_tags' , an array should be passed .
2013-12-04 21:03:09 +01:00
*
2013-10-30 15:39:10 +01:00
* @ since 2.8 . 0
*
2015-09-28 01:01:24 +02:00
* @ param false | object | array $override Whether to override the WordPress . org Themes API . Default false .
* @ param string $action Requested action . Likely values are 'theme_information' ,
* 'feature_list' , or 'query_themes' .
* @ param object $args Arguments used to query for installer pages from the Themes API .
2013-10-30 15:39:10 +01:00
*/
$res = apply_filters ( 'themes_api' , false , $action , $args );
2010-10-05 15:24:41 +02:00
if ( ! $res ) {
2018-02-01 06:19:30 +01:00
$url = 'http://api.wordpress.org/themes/info/1.2/' ;
$url = add_query_arg (
array (
'action' => $action ,
'request' => $args ,
),
$url
);
2017-09-27 10:00:49 +02:00
2018-02-01 06:19:30 +01:00
$http_url = $url ;
2017-12-01 00:11:00 +01:00
if ( $ssl = wp_http_supports ( array ( 'ssl' ) ) ) {
2013-09-09 09:54:11 +02:00
$url = set_url_scheme ( $url , 'https' );
2017-12-01 00:11:00 +01:00
}
2013-09-09 09:54:11 +02:00
2015-02-07 07:21:22 +01:00
$http_args = array (
2017-09-27 10:00:49 +02:00
'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url ( '/' ),
2013-10-27 22:09:10 +01:00
);
2018-02-01 06:19:30 +01:00
$request = wp_remote_get ( $url , $http_args );
2013-10-27 22:09:10 +01:00
if ( $ssl && is_wp_error ( $request ) ) {
2016-08-23 16:33:30 +02:00
if ( ! wp_doing_ajax () ) {
2016-11-21 02:52:32 +01:00
trigger_error (
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
) . ' ' . __ ( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
headers_sent () || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
);
2014-04-15 03:16:14 +02:00
}
2018-02-01 06:19:30 +01:00
$request = wp_remote_get ( $http_url , $http_args );
2013-10-27 22:09:10 +01:00
}
2013-09-09 09:54:11 +02:00
2017-12-01 00:11:00 +01:00
if ( is_wp_error ( $request ) ) {
$res = new WP_Error (
'themes_api_failed' ,
2016-11-21 02:52:32 +01:00
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
),
$request -> get_error_message ()
);
2010-10-05 15:24:41 +02:00
} else {
2018-02-01 06:19:30 +01:00
$res = json_decode ( wp_remote_retrieve_body ( $request ), true );
if ( is_array ( $res ) ) {
// Object casting is required in order to match the info/1.0 format.
$res = ( object ) $res ;
} elseif ( null === $res ) {
2017-12-01 00:11:00 +01:00
$res = new WP_Error (
'themes_api_failed' ,
2016-11-21 02:52:32 +01:00
sprintf (
/* translators: %s: support forums URL */
__ ( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__ ( 'https://wordpress.org/support/' )
),
wp_remote_retrieve_body ( $request )
);
}
2018-02-01 06:19:30 +01:00
if ( isset ( $res -> error ) ) {
$res = new WP_Error ( 'themes_api_failed' , $res -> error );
}
}
// Back-compat for info/1.2 API, upgrade the theme objects in query_themes to objects.
if ( 'query_themes' == $action ) {
foreach ( $res -> themes as $i => $theme ) {
$res -> themes [ $i ] = ( object ) $theme ;
}
}
// Back-compat for info/1.2 API, downgrade the feature_list result back to an array.
if ( 'feature_list' == $action ) {
$res = ( array ) $res ;
2010-10-05 15:24:41 +02:00
}
}
2012-01-08 04:48:05 +01:00
2013-10-30 15:39:10 +01:00
/**
2016-05-22 20:01:30 +02:00
* Filters the returned WordPress . org Themes API response .
2013-10-30 15:39:10 +01:00
*
* @ since 2.8 . 0
*
2016-04-15 03:43:28 +02:00
* @ param array | object | WP_Error $res WordPress . org Themes API response .
* @ param string $action Requested action . Likely values are 'theme_information' ,
* 'feature_list' , or 'query_themes' .
* @ param object $args Arguments used to query for installer pages from the WordPress . org Themes API .
2013-10-30 15:39:10 +01:00
*/
return apply_filters ( 'themes_api_result' , $res , $action , $args );
2010-10-05 15:24:41 +02:00
}
2013-11-13 21:58:05 +01:00
/**
* Prepare themes for JavaScript .
*
* @ since 3.8 . 0
*
2018-03-25 20:10:32 +02:00
* @ param WP_Theme [] $themes Optional . Array of theme objects to prepare .
* Defaults to all allowed themes .
2013-11-13 21:58:05 +01:00
*
2013-11-15 17:42:10 +01:00
* @ return array An associative array of theme data , sorted by name .
2013-11-13 21:58:05 +01:00
*/
function wp_prepare_themes_for_js ( $themes = null ) {
2013-12-02 19:46:11 +01:00
$current_theme = get_stylesheet ();
2015-03-31 22:04:25 +02:00
/**
2016-05-22 20:01:30 +02:00
* Filters theme data before it is prepared for JavaScript .
2015-03-31 22:04:25 +02:00
*
2018-04-29 23:47:22 +02:00
* Passing a non - empty array will result in wp_prepare_themes_for_js () returning
2015-03-31 22:04:25 +02:00
* early with that value instead .
*
* @ since 4.2 . 0
*
2018-03-25 20:10:32 +02:00
* @ param array $prepared_themes An associative array of theme data . Default empty array .
* @ param WP_Theme [] | null $themes An array of theme objects to prepare , if any .
* @ param string $current_theme The current theme slug .
2015-03-31 22:04:25 +02:00
*/
2015-04-21 16:23:27 +02:00
$prepared_themes = ( array ) apply_filters ( 'pre_prepare_themes_for_js' , array (), $themes , $current_theme );
2015-03-31 22:04:25 +02:00
if ( ! empty ( $prepared_themes ) ) {
return $prepared_themes ;
}
No-JavaScript and no-Customizer support for the new Themes screen.
JavaScript is rarely disabled, but graceful degradation is still important. For example, syntax errors can occur, usually with major WP updates that overhaul entire experiences and update external libraries combined with themes or plugins doing weird or old things. If this error is due to their current theme, a user needs to be able to access the themes screen to switch away from the theme. A more subtle issue could make things painful to diagnose.
This commit renders the grid in PHP (the template is duplicated, but it lightweight, fairly mundane, and easy to sync). On Backbone render, the grid is then re-rendered from JavaScript so searches can occur. Customize and Live Preview is disabled if JS fails to kick in. If JS is disabled, old-school "Preview" links are displayed.
No-Customizer support: The customizer is only supported when the browser supports postMessage (IE8+), and if the frontend is a different domain, CORS (IE10+). We use the .hide-if-no-customize class for this. Pre-customize "Preview" links should use .hide-if-customize.
The .load-customize class should be used to declare a link that opens the customizer. This enables customize-loader.js to intercept this link and load the customizer on top of the current window, making for a smoother experience.
fixes #25964.
Built from https://develop.svn.wordpress.org/trunk@26726
git-svn-id: http://core.svn.wordpress.org/trunk@26615 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2013-12-06 17:11:10 +01:00
// Make sure the current theme is listed first.
2015-03-31 22:04:25 +02:00
$prepared_themes [ $current_theme ] = array ();
No-JavaScript and no-Customizer support for the new Themes screen.
JavaScript is rarely disabled, but graceful degradation is still important. For example, syntax errors can occur, usually with major WP updates that overhaul entire experiences and update external libraries combined with themes or plugins doing weird or old things. If this error is due to their current theme, a user needs to be able to access the themes screen to switch away from the theme. A more subtle issue could make things painful to diagnose.
This commit renders the grid in PHP (the template is duplicated, but it lightweight, fairly mundane, and easy to sync). On Backbone render, the grid is then re-rendered from JavaScript so searches can occur. Customize and Live Preview is disabled if JS fails to kick in. If JS is disabled, old-school "Preview" links are displayed.
No-Customizer support: The customizer is only supported when the browser supports postMessage (IE8+), and if the frontend is a different domain, CORS (IE10+). We use the .hide-if-no-customize class for this. Pre-customize "Preview" links should use .hide-if-customize.
The .load-customize class should be used to declare a link that opens the customizer. This enables customize-loader.js to intercept this link and load the customizer on top of the current window, making for a smoother experience.
fixes #25964.
Built from https://develop.svn.wordpress.org/trunk@26726
git-svn-id: http://core.svn.wordpress.org/trunk@26615 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2013-12-06 17:11:10 +01:00
2013-11-13 21:58:05 +01:00
if ( null === $themes ) {
$themes = wp_get_themes ( array ( 'allowed' => true ) );
2013-12-02 19:46:11 +01:00
if ( ! isset ( $themes [ $current_theme ] ) ) {
$themes [ $current_theme ] = wp_get_theme ();
}
2013-11-13 21:58:05 +01:00
}
$updates = array ();
if ( current_user_can ( 'update_themes' ) ) {
2013-11-20 02:40:09 +01:00
$updates_transient = get_site_transient ( 'update_themes' );
if ( isset ( $updates_transient -> response ) ) {
$updates = $updates_transient -> response ;
}
2013-11-13 21:58:05 +01:00
}
2013-11-15 17:42:10 +01:00
WP_Theme :: sort_by_name ( $themes );
2014-12-20 23:47:22 +01:00
$parents = array ();
2013-11-29 09:38:09 +01:00
foreach ( $themes as $theme ) {
2017-12-01 00:11:00 +01:00
$slug = $theme -> get_stylesheet ();
2014-12-02 03:21:24 +01:00
$encoded_slug = urlencode ( $slug );
2013-11-13 21:58:05 +01:00
$parent = false ;
if ( $theme -> parent () ) {
2017-12-01 00:11:00 +01:00
$parent = $theme -> parent ();
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
$parents [ $slug ] = $parent -> get_stylesheet ();
2017-12-01 00:11:00 +01:00
$parent = $parent -> display ( 'Name' );
2013-11-13 21:58:05 +01:00
}
2015-11-01 07:40:28 +01:00
$customize_action = null ;
if ( current_user_can ( 'edit_theme_options' ) && current_user_can ( 'customize' ) ) {
2017-12-01 00:11:00 +01:00
$customize_action = esc_url (
add_query_arg (
array (
'return' => urlencode ( esc_url_raw ( remove_query_arg ( wp_removable_query_args (), wp_unslash ( $_SERVER [ 'REQUEST_URI' ] ) ) ) ),
),
wp_customize_url ( $slug )
)
);
2015-11-01 07:40:28 +01:00
}
No-JavaScript and no-Customizer support for the new Themes screen.
JavaScript is rarely disabled, but graceful degradation is still important. For example, syntax errors can occur, usually with major WP updates that overhaul entire experiences and update external libraries combined with themes or plugins doing weird or old things. If this error is due to their current theme, a user needs to be able to access the themes screen to switch away from the theme. A more subtle issue could make things painful to diagnose.
This commit renders the grid in PHP (the template is duplicated, but it lightweight, fairly mundane, and easy to sync). On Backbone render, the grid is then re-rendered from JavaScript so searches can occur. Customize and Live Preview is disabled if JS fails to kick in. If JS is disabled, old-school "Preview" links are displayed.
No-Customizer support: The customizer is only supported when the browser supports postMessage (IE8+), and if the frontend is a different domain, CORS (IE10+). We use the .hide-if-no-customize class for this. Pre-customize "Preview" links should use .hide-if-customize.
The .load-customize class should be used to declare a link that opens the customizer. This enables customize-loader.js to intercept this link and load the customizer on top of the current window, making for a smoother experience.
fixes #25964.
Built from https://develop.svn.wordpress.org/trunk@26726
git-svn-id: http://core.svn.wordpress.org/trunk@26615 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2013-12-06 17:11:10 +01:00
$prepared_themes [ $slug ] = array (
2013-11-13 21:58:05 +01:00
'id' => $slug ,
'name' => $theme -> display ( 'Name' ),
'screenshot' => array ( $theme -> get_screenshot () ), // @todo multiple
'description' => $theme -> display ( 'Description' ),
2013-12-05 20:08:10 +01:00
'author' => $theme -> display ( 'Author' , false , true ),
'authorAndUri' => $theme -> display ( 'Author' ),
2013-11-22 03:34:10 +01:00
'version' => $theme -> display ( 'Version' ),
'tags' => $theme -> display ( 'Tags' ),
2013-11-13 21:58:05 +01:00
'parent' => $parent ,
'active' => $slug === $current_theme ,
'hasUpdate' => isset ( $updates [ $slug ] ),
2017-12-01 00:11:00 +01:00
'hasPackage' => isset ( $updates [ $slug ] ) && ! empty ( $updates [ $slug ][ 'package' ] ),
2013-11-20 03:57:10 +01:00
'update' => get_theme_update_available ( $theme ),
2013-11-13 21:58:05 +01:00
'actions' => array (
2017-12-01 00:11:00 +01:00
'activate' => current_user_can ( 'switch_themes' ) ? wp_nonce_url ( admin_url ( 'themes.php?action=activate&stylesheet=' . $encoded_slug ), 'switch-theme_' . $slug ) : null ,
2015-11-01 07:40:28 +01:00
'customize' => $customize_action ,
2017-12-01 00:11:00 +01:00
'delete' => current_user_can ( 'delete_themes' ) ? wp_nonce_url ( admin_url ( 'themes.php?action=delete&stylesheet=' . $encoded_slug ), 'delete-theme_' . $slug ) : null ,
2013-11-13 21:58:05 +01:00
),
);
}
2014-12-02 03:21:24 +01:00
// Remove 'delete' action if theme has an active child
2014-12-20 23:47:22 +01:00
if ( ! empty ( $parents ) && array_key_exists ( $current_theme , $parents ) ) {
2014-12-02 03:21:24 +01:00
unset ( $prepared_themes [ $parents [ $current_theme ] ][ 'actions' ][ 'delete' ] );
}
2013-12-04 20:21:10 +01:00
/**
2016-05-22 20:01:30 +02:00
* Filters the themes prepared for JavaScript , for themes . php .
2013-12-04 20:21:10 +01:00
*
* Could be useful for changing the order , which is by name by default .
*
* @ since 3.8 . 0
*
* @ param array $prepared_themes Array of themes .
*/
No-JavaScript and no-Customizer support for the new Themes screen.
JavaScript is rarely disabled, but graceful degradation is still important. For example, syntax errors can occur, usually with major WP updates that overhaul entire experiences and update external libraries combined with themes or plugins doing weird or old things. If this error is due to their current theme, a user needs to be able to access the themes screen to switch away from the theme. A more subtle issue could make things painful to diagnose.
This commit renders the grid in PHP (the template is duplicated, but it lightweight, fairly mundane, and easy to sync). On Backbone render, the grid is then re-rendered from JavaScript so searches can occur. Customize and Live Preview is disabled if JS fails to kick in. If JS is disabled, old-school "Preview" links are displayed.
No-Customizer support: The customizer is only supported when the browser supports postMessage (IE8+), and if the frontend is a different domain, CORS (IE10+). We use the .hide-if-no-customize class for this. Pre-customize "Preview" links should use .hide-if-customize.
The .load-customize class should be used to declare a link that opens the customizer. This enables customize-loader.js to intercept this link and load the customizer on top of the current window, making for a smoother experience.
fixes #25964.
Built from https://develop.svn.wordpress.org/trunk@26726
git-svn-id: http://core.svn.wordpress.org/trunk@26615 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2013-12-06 17:11:10 +01:00
$prepared_themes = apply_filters ( 'wp_prepare_themes_for_js' , $prepared_themes );
2015-04-22 18:11:25 +02:00
$prepared_themes = array_values ( $prepared_themes );
return array_filter ( $prepared_themes );
2014-04-15 03:16:14 +02:00
}
2015-02-24 21:31:24 +01:00
/**
* Print JS templates for the theme - browsing UI in the Customizer .
*
* @ since 4.2 . 0
*/
function customize_themes_print_templates () {
?>
< script type = " text/html " id = " tmpl-customize-themes-details-view " >
< div class = " theme-backdrop " ></ div >
2017-10-01 15:48:46 +02:00
< div class = " theme-wrap wp-clearfix " role = " document " >
2015-02-24 21:31:24 +01:00
< div class = " theme-header " >
< button type = " button " class = " left dashicons dashicons-no " >< span class = " screen-reader-text " >< ? php _e ( 'Show previous theme' ); ?> </span></button>
< button type = " button " class = " right dashicons dashicons-no " >< span class = " screen-reader-text " >< ? php _e ( 'Show next theme' ); ?> </span></button>
< button type = " button " class = " close dashicons dashicons-no " >< span class = " screen-reader-text " >< ? php _e ( 'Close details dialog' ); ?> </span></button>
</ div >
2016-01-30 14:46:27 +01:00
< div class = " theme-about wp-clearfix " >
2015-02-24 21:31:24 +01:00
< div class = " theme-screenshots " >
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< # if ( data.screenshot && data.screenshot[0] ) { #>
2015-02-24 21:31:24 +01:00
< div class = " screenshot " >< img src = " { { data.screenshot[0] }} " alt = " " /></ div >
< # } else { #>
< div class = " screenshot blank " ></ div >
< # } #>
</ div >
< div class = " theme-info " >
< # if ( data.active ) { #>
< span class = " current-label " >< ? php _e ( 'Current Theme' ); ?> </span>
< # } #>
2015-08-31 05:51:21 +02:00
< h2 class = " theme-name " > {{{ data . name }}} < span class = " theme-version " >< ? php printf ( __ ( 'Version: %s' ), '{{ data.version }}' ); ?> </span></h2>
< h3 class = " theme-author " >< ? php printf ( __ ( 'By %s' ), '{{{ data.authorAndUri }}}' ); ?> </h3>
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< # if ( data.stars && 0 != data.num_ratings ) { #>
< div class = " theme-rating " >
{{{ data . stars }}}
2019-03-21 23:02:51 +01:00
< a class = " num-ratings " target = " _blank " href = " { { data.reviews_url }} " >
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< ? php
2017-10-25 00:47:46 +02:00
/* translators: %s: number of ratings */
2019-03-21 23:02:51 +01:00
echo sprintf ( __ ( '(%s ratings) <span class="screen-reader-text">link to view ratings opens in a new tab</span>' ), '{{ data.num_ratings }}' );
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
?>
2019-03-21 23:02:51 +01:00
</ a >
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
</ div >
< # } #>
< # if ( data.hasUpdate ) { #>
< div class = " notice notice-warning notice-alt notice-large " data - slug = " { { data.id }} " >
< h3 class = " notice-title " >< ? php _e ( 'Update Available' ); ?> </h3>
{{{ data . update }}}
</ div >
< # } #>
2015-02-24 21:31:24 +01:00
< # if ( data.parent ) { #>
< p class = " parent-theme " >< ? php printf ( __ ( 'This is a child theme of %s.' ), '<strong>{{{ data.parent }}}</strong>' ); ?> </p>
< # } #>
2016-11-04 18:18:26 +01:00
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< p class = " theme-description " > {{{ data . description }}} </ p >
2015-02-24 21:31:24 +01:00
< # if ( data.tags ) { #>
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< p class = " theme-tags " >< span >< ? php _e ( 'Tags:' ); ?> </span> {{{ data.tags }}}</p>
2015-02-24 21:31:24 +01:00
< # } #>
</ div >
</ div >
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< div class = " theme-actions " >
< # if ( data.active ) { #>
2018-02-13 23:15:32 +01:00
< button type = " button " class = " button button-primary customize-theme " >< ? php _e ( 'Customize' ); ?> </button>
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< # } else if ( 'installed' === data.type ) { #>
< ? php if ( current_user_can ( 'delete_themes' ) ) { ?>
< # if ( data.actions && data.actions['delete'] ) { #>
< a href = " { { { data.actions['delete'] }}} " data - slug = " { { data.id }} " class = " button button-secondary delete-theme " >< ? php _e ( 'Delete' ); ?> </a>
< # } #>
< ? php } ?>
2018-02-13 23:15:32 +01:00
< button type = " button " class = " button button-primary preview-theme " data - slug = " { { data.id }} " >< ? php _e ( 'Live Preview' ); ?> </button>
Customize: Introduce a new experience for discovering, installing, and previewing themes within the customizer.
Unify the theme-browsing and theme-customization experiences by introducing a comprehensive theme browser and installer directly accessible in the customizer. Replaces the customizer theme switcher with a full-screen panel for discovering/browsing and installing themes available on WordPress.org. Themes can now be installed and previewed directly in the customizer without entering the wp-admin context. Also includes an extensible framework for browsing and installing themes from other sources.
Also includes CSS auto-prefixing added via `grunt precommit:css`.
For details, see: https://make.wordpress.org/core/2016/10/03/feature-proposal-a-new-experience-for-discovering-installing-and-previewing-themes-in-the-customizer/
Previously [38813] but reverted in [39140].
Fixes #37661, #34843, #38666.
Props celloexpressions, folletto, westonruter, karmatosed, melchoyce, afercia.
Built from https://develop.svn.wordpress.org/trunk@41648
git-svn-id: http://core.svn.wordpress.org/trunk@41482 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2017-09-29 22:13:50 +02:00
< # } else { #>
< button type = " button " class = " button theme-install " data - slug = " { { data.id }} " >< ? php _e ( 'Install' ); ?> </button>
< button type = " button " class = " button button-primary theme-install preview " data - slug = " { { data.id }} " >< ? php _e ( 'Install & Preview' ); ?> </button>
< # } #>
</ div >
2015-02-24 21:31:24 +01:00
</ div >
</ script >
< ? php
}
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
/**
* Determines whether a theme is technically active but was paused while
* loading .
*
* For more information on this and similar theme functions , check out
* the { @ link https :// developer . wordpress . org / themes / basics / conditional - tags /
* Conditional Tags } article in the Theme Developer Handbook .
*
* @ since 5.2 . 0
*
* @ param string $theme Path to the theme directory relative to the themes directory .
* @ return bool True , if in the list of paused themes . False , not in the list .
*/
function is_theme_paused ( $theme ) {
if ( ! isset ( $GLOBALS [ '_paused_themes' ] ) ) {
return false ;
}
if ( get_stylesheet () !== $theme && get_template () !== $theme ) {
return false ;
}
return array_key_exists ( $theme , $GLOBALS [ '_paused_themes' ] );
}
/**
* Gets the error that was recorded for a paused theme .
*
* @ since 5.2 . 0
*
* @ param string $theme Path to the theme directory relative to the themes
* directory .
* @ return array | false Array of error information as it was returned by
* `error_get_last()` , or false if none was recorded .
*/
function wp_get_theme_error ( $theme ) {
if ( ! isset ( $GLOBALS [ '_paused_themes' ] ) ) {
return false ;
}
if ( ! array_key_exists ( $theme , $GLOBALS [ '_paused_themes' ] ) ) {
return false ;
}
return $GLOBALS [ '_paused_themes' ][ $theme ];
}
/**
* Tries to resume a single theme .
*
* If a redirect was provided and a functions . php file was found , we first ensure that
* functions . php file does not throw fatal errors anymore .
*
* The way it works is by setting the redirection to the error before trying to
* include the file . If the theme fails , then the redirection will not be overwritten
* with the success message and the theme will not be resumed .
*
* @ since 5.2 . 0
*
* @ param string $theme Single theme to resume .
* @ param string $redirect Optional . URL to redirect to . Default empty string .
* @ return bool | WP_Error True on success , false if `$theme` was not paused ,
* `WP_Error` on failure .
*/
function resume_theme ( $theme , $redirect = '' ) {
list ( $extension ) = explode ( '/' , $theme );
/*
* We ' ll override this later if the theme could be resumed without
* creating a fatal error .
*/
if ( ! empty ( $redirect ) ) {
$functions_path = '' ;
if ( strpos ( STYLESHEETPATH , $extension ) ) {
$functions_path = STYLESHEETPATH . '/functions.php' ;
} elseif ( strpos ( TEMPLATEPATH , $extension ) ) {
$functions_path = TEMPLATEPATH . '/functions.php' ;
}
if ( ! empty ( $functions_path ) ) {
wp_redirect (
add_query_arg (
'_error_nonce' ,
wp_create_nonce ( 'theme-resume-error_' . $theme ),
$redirect
)
);
// Load the theme's functions.php to test whether it throws a fatal error.
ob_start ();
include $functions_path ;
ob_clean ();
}
}
$result = wp_paused_themes () -> delete ( $extension );
if ( ! $result ) {
return new WP_Error (
'could_not_resume_theme' ,
__ ( 'Could not resume the theme.' )
);
}
return true ;
}
/**
* Renders an admin notice in case some themes have been paused due to errors .
*
* @ since 5.2 . 0
*/
function paused_themes_notice () {
if ( 'themes.php' === $GLOBALS [ 'pagenow' ] ) {
return ;
}
if ( ! current_user_can ( 'resume_themes' ) ) {
return ;
}
if ( ! isset ( $GLOBALS [ '_paused_themes' ] ) || empty ( $GLOBALS [ '_paused_themes' ] ) ) {
return ;
}
printf (
'<div class="notice notice-error"><p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p></div>' ,
__ ( 'One or more themes failed to load properly.' ),
__ ( 'You can find more details and make changes on the Themes screen.' ),
esc_url ( admin_url ( 'themes.php' ) ),
__ ( 'Go to the Themes screen' )
);
}