Customizer: Introduce a "panel" API to organize multiple sections into a one section.

Create a panel via `$GLOBALS['wp_customize']->add_panel( $panel_id, $args )` and use `$panel_id` for the `panel` argument in `$GLOBALS['wp_customize']->add_section( $section_id, $args )`. That's it.
As an example all widget area sections are now summarized into one panel. Feedback appreciated.

props celloexpressions.
see #27406.
Built from https://develop.svn.wordpress.org/trunk@28861


git-svn-id: http://core.svn.wordpress.org/trunk@28662 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Dominik Schilling 2014-06-26 20:17:15 +00:00
parent a21d9cdacf
commit b7c93eb3d0
39 changed files with 591 additions and 44 deletions

View File

@ -472,6 +472,11 @@ body.more-filters-opened .more-filters:focus:before {
color: $menu-highlight-text;
}
.control-panel-back:focus,
.control-panel-back:hover {
background-color: $menu-highlight-background;
color: $menu-highlight-text;
}
/* jQuery UI Slider */

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #096484;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #096484;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #e1a948;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #096484;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #096484;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #e1a948;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #c7a589;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #c7a589;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #c7a589;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #c7a589;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #c7a589;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #c7a589;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #a3b745;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #a3b745;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #a3b745;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #a3b745;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #a3b745;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #a3b745;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #888;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #888;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #04a4cc;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #888;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #888;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #04a4cc;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #e14d43;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #e14d43;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #e14d43;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #e14d43;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #e14d43;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #e14d43;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #9ebaa0;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #9ebaa0;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #9ebaa0;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #9ebaa0;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #9ebaa0;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #9ebaa0;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #dd823b;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #dd823b;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #dd823b;

File diff suppressed because one or more lines are too long

View File

@ -301,6 +301,10 @@ body.more-filters-opened .more-filters:hover, body.more-filters-opened .more-fil
background-color: #dd823b;
color: #fff; }
.control-panel-back:focus, .control-panel-back:hover {
background-color: #dd823b;
color: #fff; }
/* jQuery UI Slider */
.wp-slider .ui-slider-handle, .wp-slider .ui-slider-handle.ui-state-hover, .wp-slider .ui-slider-handle.focus {
background: #dd823b;

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,11 @@ body {
display: block;
}
#customize-controls .wp-full-overlay-sidebar-content {
overflow-y: auto;
overflow-x: hidden;
}
#customize-info {
border: none;
border-top: 1px solid #ddd;
@ -83,11 +88,6 @@ body {
line-height: 20px;
}
#customize-theme-controls {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1);
}
#customize-theme-controls .control-section {
border: none;
}
@ -103,7 +103,7 @@ body {
background: white;
}
#customize-theme-controls .control-section:hover .accordion-section-title,
#customize-theme-controls .control-section:hover > .accordion-section-title,
#customize-theme-controls .control-section .accordion-section-title:hover,
#customize-theme-controls .control-section.open .accordion-section-title,
#customize-theme-controls .control-section .accordion-section-title:focus {
@ -118,7 +118,7 @@ body {
background: #f5f5f5;
}
#customize-theme-controls .control-section:hover .accordion-section-title::after,
#customize-theme-controls .control-section:hover > .accordion-section-title::after,
#customize-theme-controls .control-section .accordion-section-title:hover::after,
#customize-theme-controls .control-section.open .accordion-section-title::after,
#customize-theme-controls .control-section .accordion-section-title:focus::after {
@ -143,6 +143,138 @@ body {
margin: 0;
}
.control-section.control-panel > .accordion-section-title:after {
content: "\f139";
}
.accordion-sub-container.control-panel-content {
display: none;
position: absolute;
right: 300px;
top: 0;
width: 300px;
border-top: 1px solid #ddd;
-webkit-transition: right ease-in-out .18s;
transition: right ease-in-out .18s;
}
.accordion-sub-container.control-panel-content.animating {
display: block;
}
.current-panel .accordion-sub-container.control-panel-content {
width: 100%;
}
.control-panel-back {
display: block;
position: fixed;
top: 0;
z-index: 99;
right: -48px;
width: 45px;
height: 45px;
padding-left: 2px;
background: #eee;
border-left: 1px solid #ddd;
cursor: pointer;
-webkit-transition: right ease-in-out .18s, color ease-in .1s;
transition: right ease-in-out .18s, color ease-in .1s;
}
.collapsed .control-panel-back {
display: none;
}
.control-panel-back:focus,
.control-panel-back:hover {
background-color: #0074a2;
color: #fff;
outline: none;
}
.control-panel-back:before {
font: normal 29px/1 dashicons;
content: "\f340";
position: relative;
top: 9px;
right: 9px;
}
.current-panel .control-panel-back {
right: 0;
}
.current-panel > .accordion-section-title {
height: 22px;
}
#customize-header-actions a.back {
position: relative;
right: 0;
-webkit-transition: right ease-in-out .18s;
transition: right ease-in-out .18s;
}
.in-sub-panel #customize-header-actions a.back {
right: -120px;
}
.wp-full-overlay-sidebar .wp-full-overlay-header {
-webkit-transition: padding ease-in-out .18s;
transition: padding ease-in-out .18s;
}
.in-sub-panel .wp-full-overlay-sidebar .wp-full-overlay-header {
padding-right: 62px;
}
#customize-info,
#customize-theme-controls > ul > .accordion-section {
position: relative;
right: 0;
-webkit-transition: right ease-in-out .18s;
transition: right ease-in-out .18s;
}
.in-sub-panel #customize-info,
.in-sub-panel #customize-theme-controls > ul > .accordion-section {
right: -300px;
width: 300px;
}
.in-sub-panel #customize-theme-controls .accordion-section.current-panel {
width: 100%;
}
#customize-theme-controls .control-section.current-panel {
padding: 0;
}
#customize-theme-controls .control-section > h3.accordion-section-title {
position: relative;
right: 0;
}
#customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
right: -300px;
-webkit-transition: right ease-in-out .18s;
transition: right ease-in-out .18s;
}
.control-section.control-panel .accordion-section-title .panel-title {
font-size: 20px;
font-weight: 200;
line-height: 24px;
display: block;
border: none;
}
.control-section.control-panel .preview-notice {
font-size: 13px;
line-height: 24px;
}
.customize-control {
width: 100%;
float: right;

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,11 @@ body {
display: block;
}
#customize-controls .wp-full-overlay-sidebar-content {
overflow-y: auto;
overflow-x: hidden;
}
#customize-info {
border: none;
border-top: 1px solid #ddd;
@ -83,11 +88,6 @@ body {
line-height: 20px;
}
#customize-theme-controls {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1);
}
#customize-theme-controls .control-section {
border: none;
}
@ -103,7 +103,7 @@ body {
background: white;
}
#customize-theme-controls .control-section:hover .accordion-section-title,
#customize-theme-controls .control-section:hover > .accordion-section-title,
#customize-theme-controls .control-section .accordion-section-title:hover,
#customize-theme-controls .control-section.open .accordion-section-title,
#customize-theme-controls .control-section .accordion-section-title:focus {
@ -118,7 +118,7 @@ body {
background: #f5f5f5;
}
#customize-theme-controls .control-section:hover .accordion-section-title::after,
#customize-theme-controls .control-section:hover > .accordion-section-title::after,
#customize-theme-controls .control-section .accordion-section-title:hover::after,
#customize-theme-controls .control-section.open .accordion-section-title::after,
#customize-theme-controls .control-section .accordion-section-title:focus::after {
@ -143,6 +143,138 @@ body {
margin: 0;
}
.control-section.control-panel > .accordion-section-title:after {
content: "\f139";
}
.accordion-sub-container.control-panel-content {
display: none;
position: absolute;
left: 300px;
top: 0;
width: 300px;
border-top: 1px solid #ddd;
-webkit-transition: left ease-in-out .18s;
transition: left ease-in-out .18s;
}
.accordion-sub-container.control-panel-content.animating {
display: block;
}
.current-panel .accordion-sub-container.control-panel-content {
width: 100%;
}
.control-panel-back {
display: block;
position: fixed;
top: 0;
z-index: 99;
left: -48px;
width: 45px;
height: 45px;
padding-right: 2px;
background: #eee;
border-right: 1px solid #ddd;
cursor: pointer;
-webkit-transition: left ease-in-out .18s, color ease-in .1s;
transition: left ease-in-out .18s, color ease-in .1s;
}
.collapsed .control-panel-back {
display: none;
}
.control-panel-back:focus,
.control-panel-back:hover {
background-color: #0074a2;
color: #fff;
outline: none;
}
.control-panel-back:before {
font: normal 29px/1 dashicons;
content: "\f340";
position: relative;
top: 9px;
left: 9px;
}
.current-panel .control-panel-back {
left: 0;
}
.current-panel > .accordion-section-title {
height: 22px;
}
#customize-header-actions a.back {
position: relative;
left: 0;
-webkit-transition: left ease-in-out .18s;
transition: left ease-in-out .18s;
}
.in-sub-panel #customize-header-actions a.back {
left: -120px;
}
.wp-full-overlay-sidebar .wp-full-overlay-header {
-webkit-transition: padding ease-in-out .18s;
transition: padding ease-in-out .18s;
}
.in-sub-panel .wp-full-overlay-sidebar .wp-full-overlay-header {
padding-left: 62px;
}
#customize-info,
#customize-theme-controls > ul > .accordion-section {
position: relative;
left: 0;
-webkit-transition: left ease-in-out .18s;
transition: left ease-in-out .18s;
}
.in-sub-panel #customize-info,
.in-sub-panel #customize-theme-controls > ul > .accordion-section {
left: -300px;
width: 300px;
}
.in-sub-panel #customize-theme-controls .accordion-section.current-panel {
width: 100%;
}
#customize-theme-controls .control-section.current-panel {
padding: 0;
}
#customize-theme-controls .control-section > h3.accordion-section-title {
position: relative;
left: 0;
}
#customize-theme-controls .control-section.current-panel > h3.accordion-section-title {
left: -300px;
-webkit-transition: left ease-in-out .18s;
transition: left ease-in-out .18s;
}
.control-section.control-panel .accordion-section-title .panel-title {
font-size: 20px;
font-weight: 200;
line-height: 24px;
display: block;
border: none;
}
.control-section.control-panel .preview-notice {
font-size: 13px;
line-height: 24px;
}
.customize-control {
width: 100%;
float: left;

File diff suppressed because one or more lines are too long

View File

@ -142,8 +142,12 @@ do_action( 'customize_controls_print_scripts' );
<div id="customize-theme-controls"><ul>
<?php
foreach ( $wp_customize->sections() as $section )
foreach ( $wp_customize->panels() as $panel ) {
$panel->maybe_render();
}
foreach ( $wp_customize->sections() as $section ) {
$section->maybe_render();
}
?>
</ul></div>
</div>

View File

@ -4,13 +4,26 @@
// Expand/Collapse on click
$( '.accordion-container' ).on( 'click keydown', '.accordion-section-title', function( e ) {
if ( e.type === 'keydown' && 13 !== e.which ) // "return" key
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
return;
}
e.preventDefault(); // Keep this AFTER the key filter above
accordionSwitch( $( this ) );
});
// Back to top level
$( '.accordion-container' ).on( 'click keydown', '.control-panel-back', function( e ) {
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
return;
}
e.preventDefault(); // Keep this AFTER the key filter above
panelSwitch( $( this ) );
});
// Re-initialize accordion when screen options are toggled
$( '.hide-postbox-tog' ).click( function () {
accordionInit();
@ -33,8 +46,14 @@
siblings = section.closest( '.accordion-container' ).find( '.open' ),
content = section.find( sectionContent );
if ( section.hasClass( 'cannot-expand' ) )
if ( section.hasClass( 'cannot-expand' ) ) {
return;
}
if ( section.hasClass( 'control-panel' ) ) {
panelSwitch( section );
return;
}
if ( section.hasClass( 'open' ) ) {
section.toggleClass( 'open' );
@ -49,6 +68,30 @@
accordionInit();
}
function panelSwitch( panel ) {
var position,
section = panel.closest( '.accordion-section' ),
container = section.closest( '.wp-full-overlay' ),
siblings = container.find( '.accordion-section.open' ),
content = section.find( '.control-panel-content' );
if ( section.hasClass( 'current-panel' ) ) {
section.toggleClass( 'current-panel' );
container.toggleClass( 'in-sub-panel' );
content.delay( 180 ).hide( 0, function() {
content.css( 'margin-top', 'inherit' ); // Reset
} );
} else {
siblings.removeClass( 'open' );
content.show( 0, function() {
position = content.offset().top;
content.css( 'margin-top', ( 45 - position ) );
section.toggleClass( 'current-panel' );
container.toggleClass( 'in-sub-panel' );
} );
}
}
// Initialize the accordion (currently just corner fixes)
accordionInit();

View File

@ -1 +1 @@
!function(a){function b(){d.removeClass("top bottom"),d.filter(":visible").first().addClass("top"),d.filter(":visible").last().addClass("bottom").find(e).addClass("bottom")}function c(a){var c=a.closest(".accordion-section"),d=c.closest(".accordion-container").find(".open"),f=c.find(e);c.hasClass("cannot-expand")||(c.hasClass("open")?(c.toggleClass("open"),f.toggle(!0).slideToggle(150)):(d.removeClass("open"),d.find(e).show().slideUp(150),f.toggle(!1).slideToggle(150),c.toggleClass("open")),b())}a(document).ready(function(){a(".accordion-container").on("click keydown",".accordion-section-title",function(b){("keydown"!==b.type||13===b.which)&&(b.preventDefault(),c(a(this)))}),a(".hide-postbox-tog").click(function(){b()})});var d=a(".accordion-container li.accordion-section"),e=a(".accordion-section-content");b()}(jQuery);
!function(a){function b(){e.removeClass("top bottom"),e.filter(":visible").first().addClass("top"),e.filter(":visible").last().addClass("bottom").find(f).addClass("bottom")}function c(a){var c=a.closest(".accordion-section"),e=c.closest(".accordion-container").find(".open"),g=c.find(f);if(!c.hasClass("cannot-expand")){if(c.hasClass("control-panel"))return void d(c);c.hasClass("open")?(c.toggleClass("open"),g.toggle(!0).slideToggle(150)):(e.removeClass("open"),e.find(f).show().slideUp(150),g.toggle(!1).slideToggle(150),c.toggleClass("open")),b()}}function d(a){var b,c=a.closest(".accordion-section"),d=c.closest(".wp-full-overlay"),e=d.find(".accordion-section.open"),f=c.find(".control-panel-content");c.hasClass("current-panel")?(c.toggleClass("current-panel"),d.toggleClass("in-sub-panel"),f.delay(180).hide(0,function(){f.css("margin-top","inherit")})):(e.removeClass("open"),f.show(0,function(){b=f.offset().top,f.css("margin-top",45-b),c.toggleClass("current-panel"),d.toggleClass("in-sub-panel")}))}a(document).ready(function(){a(".accordion-container").on("click keydown",".accordion-section-title",function(b){("keydown"!==b.type||13===b.which)&&(b.preventDefault(),c(a(this)))}),a(".accordion-container").on("click keydown",".control-panel-back",function(b){("keydown"!==b.type||13===b.which)&&(b.preventDefault(),d(a(this)))}),a(".hide-postbox-tog").click(function(){b()})});var e=a(".accordion-container li.accordion-section"),f=a(".accordion-section-content");b()}(jQuery);

View File

@ -45,6 +45,7 @@ final class WP_Customize_Manager {
public $widgets;
protected $settings = array();
protected $panels = array();
protected $sections = array();
protected $controls = array();
@ -314,6 +315,17 @@ final class WP_Customize_Manager {
return $this->sections;
}
/**
* Get the registered panels.
*
* @since 4.0.0
*
* @return array
*/
public function panels() {
return $this->panels;
}
/**
* Checks if the current theme is active.
*
@ -647,6 +659,50 @@ final class WP_Customize_Manager {
unset( $this->settings[ $id ] );
}
/**
* Add a customize panel.
*
* @since 4.0.0
*
* @param WP_Customize_Panel|string $id Customize Panel object, or Panel ID.
* @param array $args Panel arguments.
*/
public function add_panel( $id, $args = array() ) {
if ( is_a( $id, 'WP_Customize_Panel' ) ) {
$panel = $id;
}
else {
$panel = new WP_Customize_Panel( $this, $id, $args );
}
$this->panels[ $panel->id ] = $panel;
}
/**
* Retrieve a customize panel.
*
* @since 4.0.0
*
* @param string $id Panel ID.
* @return WP_Customize_Panel
*/
public function get_panel( $id ) {
if ( isset( $this->panels[ $id ] ) ) {
return $this->panels[ $id ];
}
}
/**
* Remove a customize panel.
*
* @since 4.0.0
*
* @param string $id Panel ID.
*/
public function remove_panel( $id ) {
unset( $this->panels[ $id ] );
}
/**
* Add a customize section.
*
@ -749,7 +805,7 @@ final class WP_Customize_Manager {
}
/**
* Prepare settings and sections.
* Prepare panels, sections, and controls.
*
* For each, check if required related components exist,
* whether the user has the necessary capabilities,
@ -763,8 +819,9 @@ final class WP_Customize_Manager {
$controls = array();
foreach ( $this->controls as $id => $control ) {
if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() )
if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) {
continue;
}
$this->sections[ $control->section ]->controls[] = $control;
$controls[ $id ] = $control;
@ -778,13 +835,39 @@ final class WP_Customize_Manager {
$sections = array();
foreach ( $this->sections as $section ) {
if ( ! $section->check_capabilities() || ! $section->controls )
if ( ! $section->check_capabilities() || ! $section->controls ) {
continue;
}
usort( $section->controls, array( $this, '_cmp_priority' ) );
if ( ! $section->panel ) {
// Top-level section.
$sections[] = $section;
} else {
// This section belongs to a panel.
if ( isset( $this->panels [ $section->panel ] ) ) {
$this->panels[ $section->panel ]->sections[] = $section;
}
}
}
$this->sections = $sections;
// Prepare panels.
// Reversing makes uasort sort by time added when conflicts occur.
$this->panels = array_reverse( $this->panels );
uasort( $this->panels, array( $this, '_cmp_priority' ) );
$panels = array();
foreach ( $this->panels as $panel ) {
if ( ! $panel->check_capabilities() || ! $panel->sections ) {
continue;
}
usort( $panel->sections, array( $this, '_cmp_priority' ) );
$panels[] = $panel;
}
$this->panels = $panels;
}
/**

View File

@ -37,6 +37,15 @@ class WP_Customize_Section {
*/
public $priority = 10;
/**
* Panel in which to show the section, making it a sub-section.
*
* @since 4.0.0
* @access public
* @var string
*/
public $panel = '';
/**
* Capability required for the section.
*
@ -162,8 +171,12 @@ class WP_Customize_Section {
* @since 3.4.0
*/
protected function render() {
$classes = 'control-section accordion-section';
if ( $this->panel ) {
$classes .= ' control-subsection';
}
?>
<li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="control-section accordion-section">
<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 ); ?></h3>
<ul class="accordion-section-content">
<?php if ( ! empty( $this->description ) ) : ?>
@ -178,3 +191,77 @@ class WP_Customize_Section {
<?php
}
}
/**
* Customize Panel Class.
*
* A UI container for sections, managed by the WP_Customize_Manager.
*
* @package WordPress
* @subpackage Customize
* @since 4.0.0
*/
class WP_Customize_Panel extends WP_Customize_Section {
/**
* Customizer sections for this panel.
*
* @since 4.0.0
* @access public
* @var array
*/
public $sections;
/**
* Constructor.
*
* Any supplied $args override class property defaults.
*
* @since 4.0.0
*
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
* @param string $id An specific ID of the section.
* @param array $args Section arguments.
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
$this->sections = array(); // Users cannot customize the $sections array.
return $this;
}
/**
* Render the panel, and the sections that have been added to it.
*
* @since 4.0.0
*/
protected function render() {
?>
<li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="control-section control-panel accordion-section">
<h3 class="accordion-section-title" tabindex="0"><?php echo esc_html( $this->title ); ?></h3>
<span class="control-panel-back" tabindex="0"><span class="screen-reader-text">Back to Customize</span></span>
<ul class="accordion-sub-container control-panel-content">
<li class="accordion-section control-section<?php if ( empty( $this->description ) ) echo ' cannot-expand'; ?>">
<div class="accordion-section-title" tabindex="0">
<span class="preview-notice"><?php
/* translators: %s is the panel title in the Customize/Live Preview pane */
echo sprintf( 'You are customizing %s', '<strong class="panel-title">' . esc_html( $this->title ) . '</strong>' );
?></span>
</div>
<?php if ( ! empty( $this->description ) ) : ?>
<div class="accordion-section-content description">
<?php echo $this->description; ?>
</div>
<?php endif; ?>
</li>
<?php
foreach ( $this->sections as $section ) {
$section->maybe_render();
}
?>
</ul>
</li>
<?php
}
}

View File

@ -433,6 +433,11 @@ final class WP_Customize_Widgets {
$this->manager->add_setting( $setting_id, $setting_args );
}
$this->manager->add_panel( 'widgets', array(
'title' => __( 'Widgets' ),
'description' => __( 'Widgets are independent sections of content that can be placed into widgetized areas provided by your theme (commonly called sidebars).' ),
) );
foreach ( $sidebars_widgets as $sidebar_id => $sidebar_widget_ids ) {
if ( empty( $sidebar_widget_ids ) ) {
$sidebar_widget_ids = array();
@ -458,10 +463,10 @@ final class WP_Customize_Widgets {
if ( $is_active_sidebar ) {
$section_args = array(
/* translators: %s: sidebar name */
'title' => sprintf( __( 'Widgets: %s' ), $GLOBALS['wp_registered_sidebars'][$sidebar_id]['name'] ),
'title' => $GLOBALS['wp_registered_sidebars'][ $sidebar_id ]['name'],
'description' => $GLOBALS['wp_registered_sidebars'][ $sidebar_id ]['description'],
'priority' => 1000 + array_search( $sidebar_id, array_keys( $wp_registered_sidebars ) ),
'priority' => array_search( $sidebar_id, array_keys( $wp_registered_sidebars ) ),
'panel' => 'widgets',
);
/**