Add theme browsing and theme switching to the Customizer

* Brings into core the Customizer Theme Switcher feature plugin
* You can now browse, preview, and activate themes right from the Customizer

fixes #31303.
props celloexpressions, afercia, westonruter, folletto, designsimply

git-svn-id: https://develop.svn.wordpress.org/trunk@31533 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Mark Jaquith
2015-02-24 20:30:22 +00:00
parent e365b3a364
commit f1bb5c2fd7
9 changed files with 853 additions and 42 deletions

View File

@@ -650,14 +650,33 @@ function wp_admin_bar_comments_menu( $wp_admin_bar ) {
function wp_admin_bar_appearance_menu( $wp_admin_bar ) {
$wp_admin_bar->add_group( array( 'parent' => 'site-name', 'id' => 'appearance' ) );
if ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
$wp_admin_bar->add_menu( array( 'parent' => 'appearance', 'id' => 'themes', 'title' => __('Themes'), 'href' => admin_url('themes.php') ) );
if ( ! current_user_can( 'edit_theme_options' ) )
return;
$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$customize_url = add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() );
if ( current_user_can( 'switch_themes' ) ) {
$wp_admin_bar->add_menu( array(
'parent' => 'appearance',
'id' => 'themes',
'title' => __( 'Themes' ),
'href' => admin_url( 'themes.php' ),
'meta' => array(
'class' => 'hide-if-customize',
),
) );
if ( current_user_can( 'customize' ) ) {
$wp_admin_bar->add_menu( array(
'parent' => 'appearance',
'id' => 'customize-themes',
'title' => __( 'Themes' ),
'href' => add_query_arg( urlencode( 'autofocus[section]' ), 'themes', $customize_url ), // urlencode() needed due to #16859
'meta' => array(
'class' => 'hide-if-no-customize',
),
) );
}
}
if ( current_user_can( 'customize' ) ) {
$wp_admin_bar->add_menu( array(
'parent' => 'appearance',
@@ -671,6 +690,10 @@ function wp_admin_bar_appearance_menu( $wp_admin_bar ) {
add_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' );
}
if ( ! current_user_can( 'edit_theme_options' ) ) {
return;
}
if ( current_theme_supports( 'widgets' ) ) {
$wp_admin_bar->add_menu( array(
'parent' => 'appearance',

View File

@@ -1100,6 +1100,101 @@ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
}
}
/**
* Customize Theme Control Class
*
* @package WordPress
* @subpackage Customize
* @since 4.2.0
*/
class WP_Customize_Theme_Control extends WP_Customize_Control {
public $type = 'theme';
public $theme;
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @since 4.2.0
* @uses WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['theme'] = $this->theme;
}
/**
* Don't render the control content from PHP, as it's rendered via JS on load.
*
* @since 4.2.0
*/
public function render_content() {}
/**
* Render a JS template for theme display.
*
* @since 4.2.0
*/
public function content_template() {
?>
<div class="theme<# if ( data.theme.active ) { #> active<# } #>" tabindex="0" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">
<# if ( data.theme.screenshot[0] ) { #>
<div class="theme-screenshot">
<img src="{{ data.theme.screenshot[0] }}" alt="" />
</div>
<# } else { #>
<div class="theme-screenshot blank"></div>
<# } #>
<span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Theme Details' ); ?></span>
<div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div>
<# if ( data.theme.active ) { #>
<h3 class="theme-name" id="{{ data.theme.id }}-name"><span><?php _ex( 'Previewing:', 'theme' ); ?></span> {{ data.theme.name }}</h3>
<# } else { #>
<h3 class="theme-name" id="{{ data.theme.id }}-name">{{ data.theme.name }}</h3>
<# } #>
<# if ( ! data.theme.active ) { #>
<div class="theme-actions">
<a class="button" href="<?php echo add_query_arg( 'theme', '{{ data.theme.id }}', remove_query_arg( 'theme' ) ); ?>" target="_top"><?php _e( 'Live Preview' ); ?></a>
</div>
<# } #>
</div>
<?php
}
}
/**
* Customize New Theme Control Class
*
* @package WordPress
* @subpackage Customize
* @since 4.2.0
*/
class WP_Customize_New_Theme_Control extends WP_Customize_Control {
/**
* Render the new control.
*
* @since 4.2.0
*/
public function render() {
if ( is_multisite() || ! current_user_can( 'install_themes') ) {
return;
}
?>
<div class="theme add-new-theme">
<a href="<?php echo admin_url( 'theme-install.php' ); ?>" target="_top">
<div class="theme-screenshot">
<span></span>
</div>
<h3 class="theme-name"><?php _e( 'Add New Theme' ); ?></h3>
</a>
</div>
<?php
}
}
/**
* Widget Area Customize Control Class
*

View File

@@ -1110,6 +1110,38 @@ final class WP_Customize_Manager {
$this->register_control_type( 'WP_Customize_Upload_Control' );
$this->register_control_type( 'WP_Customize_Image_Control' );
$this->register_control_type( 'WP_Customize_Background_Image_Control' );
$this->register_control_type( 'WP_Customize_Theme_Control' );
/* Themes */
$this->add_section( new WP_Customize_Themes_Section( $this, 'themes', array(
'title' => sprintf( __( 'Theme: %s' ), $this->theme()->display('Name') ),
'capability' => 'switch_themes',
'priority' => 0,
) ) );
// Themes Setting (unused - the theme is considerably more fundamental to the Customizer experience).
$this->add_setting( new WP_Customize_Filter_Setting( $this, 'active_theme', array(
'capability' => 'switch_themes',
) ) );
require_once( ABSPATH . 'wp-admin/includes/theme.php' );
// Theme Controls.
$themes = wp_prepare_themes_for_js();
foreach ( $themes as $theme ) {
$theme_id = 'theme_' . $theme['id'];
$this->add_control( new WP_Customize_Theme_Control( $this, $theme_id, array(
'theme' => $theme,
'section' => 'themes',
'settings' => 'active_theme',
) ) );
}
$this->add_control( new WP_Customize_New_Theme_Control( $this, 'add_theme', array(
'section' => 'themes',
'settings' => 'active_theme',
) ) );
/* Site Title & Tagline */

View File

@@ -311,6 +311,57 @@ class WP_Customize_Section {
}
}
/**
* Customize Themes Section Class.
*
* A UI container for theme controls, which behaves like a backwards Panel.
*
* @package WordPress
* @subpackage Customize
* @since 4.2.0
*/
class WP_Customize_Themes_Section extends WP_Customize_Section {
public $type = 'themes';
/**
* Render the themes section, which behaves like a panel.
*
* @since 4.2.0
*/
protected function render() {
$classes = 'accordion-section control-section control-section-' . $this->type;
?>
<li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
<h3 class="accordion-section-title" tabindex="0">
<?php echo esc_html( $this->title ); ?>
<span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span>
</h3>
<span class="control-panel-back themes-panel-back" tabindex="-1"><span class="screen-reader-text"><?php _e( 'Back' ); ?></span></span>
<div class="customize-themes-panel control-panel-content themes-php">
<h2><?php esc_html_e( 'Themes' ); ?>
<span class="title-count theme-count"><?php echo count( $this->controls ) - 1; ?></span>
<?php if ( ! is_multisite() && current_user_can( 'install_themes' ) ) : ?>
<a href="<?php echo admin_url( 'theme-install.php' ); ?>" target="_top" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'Add new theme' ); ?></a>
<?php endif; ?>
</h2>
<div class="theme-overlay" tabindex="0" role="dialog" aria-label="<?php esc_attr_e( 'Theme details' ); ?>"></div>
<div id="customize-container"></div>
<?php if ( 6 < count( $this->controls ) ) : ?>
<p><label for="themes-filter">
<span class="screen-reader-text"><?php _e( 'Search installed themes...' ); ?></span>
<input type="search" id="themes-filter" placeholder="<?php esc_attr_e( 'Search installed themes...' ); ?>" />
</label></p>
<?php endif; ?>
<div class="theme-browser rendered">
<ul class="themes accordion-section-content">
</ul>
</div>
</div>
</li>
<?php }
}
/**
* Customizer section representing widget area (sidebar).
*

View File

@@ -11,7 +11,7 @@ $wp_version = '4.2-alpha-31007-src';
*
* @global int $wp_db_version
*/
$wp_db_version = 31351;
$wp_db_version = 31532;
/**
* Holds the TinyMCE version