WordPress.org

Make WordPress Core

Changeset 28861


Ignore:
Timestamp:
06/26/14 20:16:21 (3 years ago)
Author:
ocean90
Message:

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.

Location:
trunk/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src

    • Property svn:ignore
      •  

        old new  
        11.wp-tests-version 
        22.htaccess 
         3web-store-experiences 
  • trunk/src/wp-admin/css/colors/_admin.scss

    r28127 r28861  
    473473} 
    474474 
     475.control-panel-back:focus, 
     476.control-panel-back:hover { 
     477    background-color: $menu-highlight-background; 
     478    color: $menu-highlight-text; 
     479} 
    475480 
    476481/* jQuery UI Slider */ 
  • trunk/src/wp-admin/css/customize-controls.css

    r28086 r28861  
    3131.saving #customize-header-actions .spinner { 
    3232    display: block; 
     33} 
     34 
     35#customize-controls .wp-full-overlay-sidebar-content { 
     36    overflow-y: auto; 
     37    overflow-x: hidden; 
    3338} 
    3439 
     
    8489} 
    8590 
    86 #customize-theme-controls { 
    87     -webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); 
    88     box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); 
    89 } 
    90  
    9191#customize-theme-controls .control-section { 
    9292    border: none; 
     
    104104} 
    105105 
    106 #customize-theme-controls .control-section:hover .accordion-section-title, 
     106#customize-theme-controls .control-section:hover > .accordion-section-title, 
    107107#customize-theme-controls .control-section .accordion-section-title:hover, 
    108108#customize-theme-controls .control-section.open .accordion-section-title, 
     
    119119} 
    120120 
    121 #customize-theme-controls .control-section:hover .accordion-section-title::after, 
     121#customize-theme-controls .control-section:hover > .accordion-section-title::after, 
    122122#customize-theme-controls .control-section .accordion-section-title:hover::after, 
    123123#customize-theme-controls .control-section.open .accordion-section-title::after, 
     
    142142#customize-theme-controls .accordion-section-content { 
    143143    margin: 0; 
     144} 
     145 
     146.control-section.control-panel > .accordion-section-title:after { 
     147    content: "\f139"; 
     148} 
     149 
     150.accordion-sub-container.control-panel-content { 
     151    display: none; 
     152    position: absolute; 
     153    left: 300px; 
     154    top: 0; 
     155    width: 300px; 
     156    border-top: 1px solid #ddd; 
     157    -webkit-transition: left ease-in-out .18s; 
     158    transition: left ease-in-out .18s; 
     159} 
     160 
     161.accordion-sub-container.control-panel-content.animating { 
     162    display: block; 
     163} 
     164 
     165.current-panel .accordion-sub-container.control-panel-content { 
     166    width: 100%; 
     167} 
     168 
     169.control-panel-back { 
     170    display: block; 
     171    position: fixed; 
     172    top: 0; 
     173    z-index: 99; 
     174    left: -48px; 
     175    width: 45px; 
     176    height: 45px; 
     177    padding-right: 2px; 
     178    background: #eee; 
     179    border-right: 1px solid #ddd; 
     180    cursor: pointer; 
     181    -webkit-transition: left ease-in-out .18s, color ease-in .1s; 
     182    transition: left ease-in-out .18s, color ease-in .1s; 
     183} 
     184 
     185.collapsed .control-panel-back { 
     186    display: none; 
     187} 
     188 
     189.control-panel-back:focus, 
     190.control-panel-back:hover { 
     191    background-color: #0074a2; 
     192    color: #fff; 
     193    outline: none; 
     194} 
     195 
     196.control-panel-back:before { 
     197    font: normal 29px/1 dashicons; 
     198    content: "\f340"; 
     199    position: relative; 
     200    top: 9px; 
     201    left: 9px; 
     202} 
     203 
     204.current-panel .control-panel-back { 
     205    left: 0; 
     206} 
     207 
     208.current-panel > .accordion-section-title { 
     209    height: 22px; 
     210} 
     211 
     212#customize-header-actions a.back { 
     213    position: relative; 
     214    left: 0; 
     215    -webkit-transition: left ease-in-out .18s; 
     216    transition: left ease-in-out .18s; 
     217} 
     218 
     219.in-sub-panel #customize-header-actions a.back { 
     220    left: -120px; 
     221} 
     222 
     223.wp-full-overlay-sidebar .wp-full-overlay-header { 
     224    -webkit-transition: padding ease-in-out .18s; 
     225    transition: padding ease-in-out .18s; 
     226} 
     227 
     228.in-sub-panel .wp-full-overlay-sidebar .wp-full-overlay-header { 
     229    padding-left: 62px; 
     230} 
     231 
     232#customize-info, 
     233#customize-theme-controls > ul > .accordion-section { 
     234    position: relative; 
     235    left: 0; 
     236    -webkit-transition: left ease-in-out .18s; 
     237    transition: left ease-in-out .18s; 
     238} 
     239 
     240.in-sub-panel #customize-info, 
     241.in-sub-panel #customize-theme-controls > ul > .accordion-section { 
     242    left: -300px; 
     243    width: 300px; 
     244} 
     245 
     246.in-sub-panel #customize-theme-controls .accordion-section.current-panel { 
     247    width: 100%; 
     248} 
     249 
     250#customize-theme-controls .control-section.current-panel { 
     251    padding: 0; 
     252} 
     253 
     254#customize-theme-controls .control-section > h3.accordion-section-title { 
     255    position: relative; 
     256    left: 0; 
     257} 
     258 
     259#customize-theme-controls .control-section.current-panel > h3.accordion-section-title { 
     260    left: -300px; 
     261    -webkit-transition: left ease-in-out .18s; 
     262    transition: left ease-in-out .18s; 
     263} 
     264 
     265.control-section.control-panel .accordion-section-title .panel-title { 
     266    font-size: 20px; 
     267    font-weight: 200; 
     268    line-height: 24px; 
     269    display: block; 
     270    border: none; 
     271} 
     272 
     273.control-section.control-panel .preview-notice { 
     274    font-size: 13px; 
     275    line-height: 24px; 
    144276} 
    145277 
  • trunk/src/wp-admin/customize.php

    r28482 r28861  
    143143            <div id="customize-theme-controls"><ul> 
    144144                <?php 
    145                 foreach ( $wp_customize->sections() as $section ) 
     145                foreach ( $wp_customize->panels() as $panel ) { 
     146                    $panel->maybe_render(); 
     147                } 
     148                foreach ( $wp_customize->sections() as $section ) { 
    146149                    $section->maybe_render(); 
     150                } 
    147151                ?> 
    148152            </ul></div> 
  • trunk/src/wp-admin/js/accordion.js

    r24734 r28861  
    55        // Expand/Collapse on click 
    66        $( '.accordion-container' ).on( 'click keydown', '.accordion-section-title', function( e ) { 
    7             if ( e.type === 'keydown' && 13 !== e.which ) // "return" key 
    8                     return; 
     7            if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key 
     8                return; 
     9            } 
     10 
    911            e.preventDefault(); // Keep this AFTER the key filter above 
    1012 
    1113            accordionSwitch( $( this ) ); 
     14        }); 
     15 
     16        // Back to top level 
     17        $( '.accordion-container' ).on( 'click keydown', '.control-panel-back', function( e ) { 
     18            if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key 
     19                return; 
     20            } 
     21 
     22            e.preventDefault(); // Keep this AFTER the key filter above 
     23 
     24            panelSwitch( $( this ) ); 
    1225        }); 
    1326 
     
    3447            content = section.find( sectionContent ); 
    3548 
    36         if ( section.hasClass( 'cannot-expand' ) ) 
     49        if ( section.hasClass( 'cannot-expand' ) ) { 
    3750            return; 
     51        } 
     52 
     53        if ( section.hasClass( 'control-panel' ) ) { 
     54            panelSwitch( section ); 
     55            return; 
     56        } 
    3857 
    3958        if ( section.hasClass( 'open' ) ) { 
     
    5069    } 
    5170 
     71    function panelSwitch( panel ) { 
     72        var position, 
     73            section = panel.closest( '.accordion-section' ), 
     74            container = section.closest( '.wp-full-overlay' ), 
     75            siblings = container.find( '.accordion-section.open' ), 
     76            content = section.find( '.control-panel-content' ); 
     77 
     78        if ( section.hasClass( 'current-panel' ) ) { 
     79            section.toggleClass( 'current-panel' ); 
     80            container.toggleClass( 'in-sub-panel' ); 
     81            content.delay( 180 ).hide( 0, function() { 
     82                content.css( 'margin-top', 'inherit' ); // Reset 
     83            } ); 
     84        } else { 
     85            siblings.removeClass( 'open' ); 
     86            content.show( 0, function() { 
     87                position = content.offset().top; 
     88                content.css( 'margin-top', ( 45 - position ) ); 
     89                section.toggleClass( 'current-panel' ); 
     90                container.toggleClass( 'in-sub-panel' ); 
     91            } ); 
     92        } 
     93    } 
     94 
    5295    // Initialize the accordion (currently just corner fixes) 
    5396    accordionInit(); 
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r28546 r28861  
    4646 
    4747    protected $settings = array(); 
     48    protected $panels   = array(); 
    4849    protected $sections = array(); 
    4950    protected $controls = array(); 
     
    313314    public function sections() { 
    314315        return $this->sections; 
     316    } 
     317 
     318    /** 
     319     * Get the registered panels. 
     320     * 
     321     * @since 4.0.0 
     322     * 
     323     * @return array 
     324     */ 
     325    public function panels() { 
     326        return $this->panels; 
    315327    } 
    316328 
     
    649661 
    650662    /** 
     663     * Add a customize panel. 
     664     * 
     665     * @since 4.0.0 
     666     * 
     667     * @param WP_Customize_Panel|string $id   Customize Panel object, or Panel ID. 
     668     * @param array                     $args Panel arguments. 
     669     */ 
     670    public function add_panel( $id, $args = array() ) { 
     671        if ( is_a( $id, 'WP_Customize_Panel' ) ) { 
     672            $panel = $id; 
     673        } 
     674        else { 
     675            $panel = new WP_Customize_Panel( $this, $id, $args ); 
     676        } 
     677 
     678        $this->panels[ $panel->id ] = $panel; 
     679    } 
     680 
     681    /** 
     682     * Retrieve a customize panel. 
     683     * 
     684     * @since 4.0.0 
     685     * 
     686     * @param string $id Panel ID. 
     687     * @return WP_Customize_Panel 
     688     */ 
     689    public function get_panel( $id ) { 
     690        if ( isset( $this->panels[ $id ] ) ) { 
     691            return $this->panels[ $id ]; 
     692        } 
     693    } 
     694 
     695    /** 
     696     * Remove a customize panel. 
     697     * 
     698     * @since 4.0.0 
     699     * 
     700     * @param string $id Panel ID. 
     701     */ 
     702    public function remove_panel( $id ) { 
     703        unset( $this->panels[ $id ] ); 
     704    } 
     705 
     706    /** 
    651707     * Add a customize section. 
    652708     * 
     
    750806 
    751807    /** 
    752      * Prepare settings and sections. 
     808     * Prepare panels, sections, and controls. 
    753809     * 
    754810     * For each, check if required related components exist, 
     
    764820 
    765821        foreach ( $this->controls as $id => $control ) { 
    766             if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) 
     822            if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) { 
    767823                continue; 
     824            } 
    768825 
    769826            $this->sections[ $control->section ]->controls[] = $control; 
     
    779836 
    780837        foreach ( $this->sections as $section ) { 
    781             if ( ! $section->check_capabilities() || ! $section->controls ) 
     838            if ( ! $section->check_capabilities() || ! $section->controls ) { 
    782839                continue; 
     840            } 
    783841 
    784842            usort( $section->controls, array( $this, '_cmp_priority' ) ); 
    785             $sections[] = $section; 
     843 
     844            if ( ! $section->panel ) { 
     845                // Top-level section. 
     846                $sections[] = $section; 
     847            } else { 
     848                // This section belongs to a panel. 
     849                if ( isset( $this->panels [ $section->panel ] ) ) { 
     850                    $this->panels[ $section->panel ]->sections[] = $section; 
     851                } 
     852            } 
    786853        } 
    787854        $this->sections = $sections; 
     855 
     856        // Prepare panels. 
     857        // Reversing makes uasort sort by time added when conflicts occur. 
     858        $this->panels = array_reverse( $this->panels ); 
     859        uasort( $this->panels, array( $this, '_cmp_priority' ) ); 
     860        $panels = array(); 
     861 
     862        foreach ( $this->panels as $panel ) { 
     863            if ( ! $panel->check_capabilities() || ! $panel->sections ) { 
     864                continue; 
     865            } 
     866 
     867            usort( $panel->sections, array( $this, '_cmp_priority' ) ); 
     868            $panels[] = $panel; 
     869        } 
     870        $this->panels = $panels; 
    788871    } 
    789872 
  • trunk/src/wp-includes/class-wp-customize-section.php

    r28827 r28861  
    3737     */ 
    3838    public $priority = 10; 
     39 
     40    /** 
     41     * Panel in which to show the section, making it a sub-section. 
     42     * 
     43     * @since 4.0.0 
     44     * @access public 
     45     * @var string 
     46     */ 
     47    public $panel = ''; 
    3948 
    4049    /** 
     
    163172     */ 
    164173    protected function render() { 
     174        $classes = 'control-section accordion-section'; 
     175        if ( $this->panel ) { 
     176            $classes .= ' control-subsection'; 
     177        } 
    165178        ?> 
    166         <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="control-section accordion-section"> 
     179        <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>"> 
    167180            <h3 class="accordion-section-title" tabindex="0"><?php echo esc_html( $this->title ); ?></h3> 
    168181            <ul class="accordion-section-content"> 
     
    179192    } 
    180193} 
     194 
     195/** 
     196 * Customize Panel Class. 
     197 * 
     198 * A UI container for sections, managed by the WP_Customize_Manager. 
     199 * 
     200 * @package WordPress 
     201 * @subpackage Customize 
     202 * @since 4.0.0 
     203 */ 
     204class WP_Customize_Panel extends WP_Customize_Section { 
     205 
     206    /** 
     207     * Customizer sections for this panel. 
     208     * 
     209     * @since 4.0.0 
     210     * @access public 
     211     * @var array 
     212     */ 
     213    public $sections; 
     214 
     215    /** 
     216     * Constructor. 
     217     * 
     218     * Any supplied $args override class property defaults. 
     219     * 
     220     * @since 4.0.0 
     221     * 
     222     * @param WP_Customize_Manager $manager Customizer bootstrap instance. 
     223     * @param string               $id      An specific ID of the section. 
     224     * @param array                $args    Section arguments. 
     225     */ 
     226    public function __construct( $manager, $id, $args = array() ) { 
     227        parent::__construct( $manager, $id, $args ); 
     228 
     229        $this->sections = array(); // Users cannot customize the $sections array. 
     230 
     231        return $this; 
     232    } 
     233 
     234    /** 
     235     * Render the panel, and the sections that have been added to it. 
     236     * 
     237     * @since 4.0.0 
     238     */ 
     239    protected function render() { 
     240        ?> 
     241        <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="control-section control-panel accordion-section"> 
     242            <h3 class="accordion-section-title" tabindex="0"><?php echo esc_html( $this->title ); ?></h3> 
     243            <span class="control-panel-back" tabindex="0"><span class="screen-reader-text">Back to Customize</span></span> 
     244            <ul class="accordion-sub-container control-panel-content"> 
     245                <li class="accordion-section control-section<?php if ( empty( $this->description ) ) echo ' cannot-expand'; ?>"> 
     246                    <div class="accordion-section-title" tabindex="0"> 
     247                        <span class="preview-notice"><?php 
     248                            /* translators: %s is the panel title in the Customize/Live Preview pane */ 
     249                            echo sprintf( 'You are customizing %s', '<strong class="panel-title">' . esc_html( $this->title ) . '</strong>' ); 
     250                        ?></span> 
     251                    </div> 
     252                    <?php if ( ! empty( $this->description ) ) : ?> 
     253                        <div class="accordion-section-content description"> 
     254                            <?php echo $this->description; ?> 
     255                        </div> 
     256                    <?php endif; ?> 
     257                </li> 
     258                <?php 
     259                foreach ( $this->sections as $section ) { 
     260                    $section->maybe_render(); 
     261                } 
     262                ?> 
     263            </ul> 
     264        </li> 
     265        <?php 
     266    } 
     267} 
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r28143 r28861  
    434434        } 
    435435 
     436        $this->manager->add_panel( 'widgets', array( 
     437            'title' => __( 'Widgets' ), 
     438            'description' => __( 'Widgets are independent sections of content that can be placed into widgetized areas provided by your theme (commonly called sidebars).' ), 
     439        ) ); 
     440 
    436441        foreach ( $sidebars_widgets as $sidebar_id => $sidebar_widget_ids ) { 
    437442            if ( empty( $sidebar_widget_ids ) ) { 
     
    459464 
    460465                    $section_args = array( 
    461                         /* translators: %s: sidebar name */ 
    462                         'title' => sprintf( __( 'Widgets: %s' ), $GLOBALS['wp_registered_sidebars'][$sidebar_id]['name'] ), 
    463                         'description' => $GLOBALS['wp_registered_sidebars'][$sidebar_id]['description'], 
    464                         'priority' => 1000 + array_search( $sidebar_id, array_keys( $wp_registered_sidebars ) ), 
     466                        'title' => $GLOBALS['wp_registered_sidebars'][ $sidebar_id ]['name'], 
     467                        'description' => $GLOBALS['wp_registered_sidebars'][ $sidebar_id ]['description'], 
     468                        'priority' => array_search( $sidebar_id, array_keys( $wp_registered_sidebars ) ), 
     469                        'panel' => 'widgets', 
    465470                    ); 
    466471 
Note: See TracChangeset for help on using the changeset viewer.