WordPress.org

Make WordPress Core

Ticket #30737: 30737.2.diff

File 30737.2.diff, 15.3 KB (added by celloexpressions, 7 years ago)

Also implement panel container templates, address feedback from @westonruter.

  • src/wp-admin/customize.php

     
    184184        <div id="customize-preview" class="wp-full-overlay-main"></div>
    185185        <?php
    186186
    187         // Render control templates.
     187        // Render Panel, Section, and Control templates.
     188        $wp_customize->render_panel_templates();
     189        $wp_customize->render_section_templates();
    188190        $wp_customize->render_control_templates();
    189191
    190192        /**
  • src/wp-admin/js/customize-controls.js

     
    149149        Container = api.Class.extend({
    150150                defaultActiveArguments: { duration: 'fast', completeCallback: $.noop },
    151151                defaultExpandedArguments: { duration: 'fast', completeCallback: $.noop },
     152                containerType: 'container',
    152153
    153154                /**
    154155                 * @since 4.1.0
     
    161162                        container.id = id;
    162163                        container.params = {};
    163164                        $.extend( container, options || {} );
     165                        container.templateSelector = 'customize-' + container.containerType + '-' + container.params.type;
    164166                        container.container = $( container.params.content );
     167                        if ( 0 === container.container.length ) {
     168                                container.container = $( container.getContainer() );
     169                        }
    165170
    166171                        container.deferred = {
    167172                                embedded: new $.Deferred()
     
    348353                 * Bring the container into view and then expand this and bring it into view
    349354                 * @param {Object} [params]
    350355                 */
    351                 focus: focus
     356                focus: focus,
     357
     358                /**
     359                 * Return the container html, generated from its JS template, if it exists.
     360                 *
     361                 * @since 4.2.0
     362                 */
     363                getContainer: function () {
     364                        var template,
     365                                container = this;
     366
     367                        if ( 0 !== $( '#tmpl-' + container.templateSelector ).length ) {
     368                                template = wp.template( container.templateSelector );
     369                                if ( template && container.container ) {
     370                                        return template( container.params );
     371                                }
     372                        }
     373
     374                        return '<li></li>';
     375                }
    352376        });
    353377
    354378        /**
     
    358382         * @augments wp.customize.Class
    359383         */
    360384        api.Section = Container.extend({
     385                containerType: 'section',
    361386
    362387                /**
    363388                 * @since 4.1.0
     
    527552         * @augments wp.customize.Class
    528553         */
    529554        api.Panel = Container.extend({
     555                containerType: 'panel',
     556
    530557                /**
    531558                 * @since 4.1.0
    532559                 *
     
    553580
    554581                        if ( ! panel.container.parent().is( parentContainer ) ) {
    555582                                parentContainer.append( panel.container );
     583                                panel.renderContent();
    556584                        }
    557585                        panel.deferred.embedded.resolve();
    558586                },
     
    575603                                }
    576604                        });
    577605
    578                         meta = panel.container.find( '.panel-meta:first' );
    579 
    580                         meta.find( '> .accordion-section-title' ).on( 'click keydown', function( event ) {
     606                        panel.container.on( 'click keydown', '.panel-meta > .accordion-section-title', function( event ) {
    581607                                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    582608                                        return;
    583609                                }
    584610                                event.preventDefault(); // Keep this AFTER the key filter above
    585611
     612                                meta = panel.container.find( '.panel-meta' );
    586613                                if ( meta.hasClass( 'cannot-expand' ) ) {
    587614                                        return;
    588615                                }
     
    704731                                panelTitle.focus();
    705732                                container.scrollTop( 0 );
    706733                        }
     734                },
     735
     736                /**
     737                 * Render the panel from its JS template, if it exists.
     738                 *
     739                 * The panel's container must already exist in the DOM.
     740                 *
     741                 * @since 4.2.0
     742                 */
     743                renderContent: function () {
     744                        var template,
     745                                panel = this;
     746
     747                        // Add the content to the container.
     748                        if ( 0 !== $( '#tmpl-' + panel.templateSelector + '-content' ).length ) {
     749                                template = wp.template( panel.templateSelector + '-content' );
     750                                if ( template && panel.container ) {
     751                                        panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) );
     752                                }
     753                        }
    707754                }
    708755        });
    709756
  • src/wp-includes/class-wp-customize-control.php

     
    259259         * @return array Array of parameters passed to the JavaScript.
    260260         */
    261261        public function json() {
     262                if ( ! $this->check_capabilities() ) {
     263                        return;
     264                }
     265
    262266                $this->to_json();
    263267                return $this->json;
    264268        }
     
    515519         * @since 4.1.0
    516520         */
    517521        final public function print_template() {
    518                 ?>
    519                 <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">
    520                         <?php $this->content_template(); ?>
    521                 </script>
    522                 <?php
     522                ?>
     523                <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">
     524                        <?php $this->content_template(); ?>
     525                </script>
     526                <?php
    523527        }
    524528
    525529        /**
  • src/wp-includes/class-wp-customize-manager.php

     
    5454        protected $customized;
    5555
    5656        /**
    57          * Controls that may be rendered from JS templates.
     57         * Panel types that may be rendered from JS templates.
    5858         *
     59         * @since 4.2.0
     60         * @access protected
     61         * @var array
     62         */
     63        protected $registered_panel_types = array();
     64
     65        /**
     66         * Section types that may be rendered from JS templates.
     67         *
     68         * @since 4.2.0
     69         * @access protected
     70         * @var array
     71         */
     72        protected $registered_section_types = array();
     73
     74        /**
     75         * Control types that may be rendered from JS templates.
     76         *
    5977         * @since 4.1.0
    6078         * @access protected
    6179         * @var array
     
    774792        }
    775793
    776794        /**
     795         * Register a customize panel type.
     796         *
     797         * Registered types are eligible to be rendered via JS and created dynamically.
     798         *
     799         * @since 4.2.0
     800         * @access public
     801         *
     802         * @param string $panel Name of a custom panel which is a subclass of
     803         *                        {@see WP_Customize_Panel}.
     804         */
     805        public function register_panel_type( $panel ) {
     806                $this->registered_panel_types[] = $panel;
     807        }
     808
     809        /**
     810         * Render JS templates for all registered panel types.
     811         *
     812         * @since 4.2.0
     813         * @access public
     814         */
     815        public function render_panel_templates() {
     816                foreach ( $this->registered_panel_types as $panel_type ) {
     817                        $panel = new $panel_type( $this, 'temp', array() );
     818                        $panel->print_template();
     819                }
     820        }
     821
     822        /**
    777823         * Add a customize section.
    778824         *
    779825         * @since 3.4.0
     
    815861        }
    816862
    817863        /**
     864         * Register a customize section type.
     865         *
     866         * Registered types are eligible to be rendered via JS and created dynamically.
     867         *
     868         * @since 4.2.0
     869         * @access public
     870         *
     871         * @param string $section Name of a custom section which is a subclass of
     872         *                        {@see WP_Customize_Section}.
     873         */
     874        public function register_section_type( $section ) {
     875                $this->registered_section_types[] = $section;
     876        }
     877
     878        /**
     879         * Render JS templates for all registered section types.
     880         *
     881         * @since 4.2.0
     882         * @access public
     883         */
     884        public function render_section_templates() {
     885                foreach ( $this->registered_section_types as $section_type ) {
     886                        $section = new $section_type( $this, 'temp', array() );
     887                        $section->print_template();
     888                }
     889        }
     890
     891        /**
    818892         * Add a customize control.
    819893         *
    820894         * @since 3.4.0
     
    9851059         */
    9861060        public function register_controls() {
    9871061
    988                 /* Control Types (custom control classes) */
     1062                /* Panel, Section, and Control Types */
     1063                $this->register_panel_type( 'WP_Customize_Panel' );
     1064                $this->register_section_type( 'WP_Customize_Section' );
     1065                $this->register_section_type( 'WP_Customize_Sidebar_Section' );
    9891066                $this->register_control_type( 'WP_Customize_Color_Control' );
    9901067                $this->register_control_type( 'WP_Customize_Upload_Control' );
    9911068                $this->register_control_type( 'WP_Customize_Image_Control' );
  • src/wp-includes/class-wp-customize-panel.php

     
    204204         * @return array The array to be exported to the client as JSON.
    205205         */
    206206        public function json() {
    207                 $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'type' ) );
     207                if ( ! $this->check_capabilities() ) {
     208                        return;
     209                }
     210
     211                $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'type' ) );
    208212                $array['content'] = $this->get_content();
    209213                $array['active'] = $this->active();
    210214                $array['instanceNumber'] = $this->instance_number;
     
    279283        }
    280284
    281285        /**
    282          * Render the panel container, and then its contents.
     286         * Render the panel container, and then its contents (via `this->render_content()`) in a subclass.
    283287         *
     288         * Panel containers are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}.
     289         *
    284290         * @since 4.0.0
    285291         * @access protected
    286292         */
    287         protected function render() {
    288                 $classes = 'accordion-section control-section control-panel control-panel-' . $this->type;
     293        protected function render() {}
     294
     295        /**
     296         * Render the panel UI in a subclass.
     297         *
     298         * Panel contents are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}.
     299         *
     300         * @since 4.1.0
     301         * @access protected
     302         */
     303        protected function render_content() {}
     304
     305        /**
     306         * Render the panel's JS templates.
     307         *
     308         * This function is only run for panel types that have been registered with
     309         * {@see WP_Customize_Manager::register_panel_type()}.
     310         *
     311         * @since 4.2.0
     312         */
     313        public function print_template() {
    289314                ?>
    290                 <li id="accordion-panel-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
     315                <script type="text/html" id="tmpl-customize-panel-<?php echo $this->type; ?>-content">
     316                        <?php $this->content_template(); ?>
     317                </script>
     318        <script type="text/html" id="tmpl-customize-panel-<?php echo $this->type; ?>">
     319                        <?php $this->render_template(); ?>
     320        </script>
     321        <?php
     322        }
     323
     324        /**
     325         * An Underscore (JS) template for rendering this panel's container.
     326         *
     327         * Class variables for this panel class are available in the `data` JS object;
     328         * export custom variables by overriding {@see WP_Customize_Panel::json()}.
     329         *
     330         * @see WP_Customize_Panel::print_template()
     331         *
     332         * @since 4.2.0
     333         */
     334        protected function render_template() {
     335                ?>
     336                <# var classes = 'accordion-section control-section control-panel control-panel-' + data.type; #>
     337                <li id="accordion-panel-{{ data.id }}" class="{{ classes }}">
    291338                        <h3 class="accordion-section-title" tabindex="0">
    292                                 <?php echo esc_html( $this->title ); ?>
     339                                {{ data.title }}
    293340                                <span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span>
    294341                        </h3>
    295                         <ul class="accordion-sub-container control-panel-content">
    296                                 <?php $this->render_content(); ?>
    297                         </ul>
     342                        <ul class="accordion-sub-container control-panel-content"></ul>
    298343                </li>
    299344                <?php
    300345        }
    301346
    302347        /**
    303          * Render the sections that have been added to the panel.
     348         * An Underscore (JS) template for this panel's content (but not its container).
    304349         *
    305          * @since 4.1.0
    306          * @access protected
     350         * Class variables for this panel class are available in the `data` JS object;
     351         * export custom variables by overriding {@see WP_Customize_Panel::json()}.
     352         *
     353         * @see WP_Customize_Panel::print_template()
     354         *
     355         * @since 4.2.0
    307356         */
    308         protected function render_content() {
     357        protected function content_template() {
    309358                ?>
    310                 <li class="panel-meta accordion-section control-section<?php if ( empty( $this->description ) ) { echo ' cannot-expand'; } ?>">
     359                <li class="panel-meta accordion-section control-section<# if ( ! data.description ) { #> cannot-expand<# } #>">
    311360                        <div class="accordion-section-title" tabindex="0">
    312361                                <span class="preview-notice"><?php
    313362                                        /* translators: %s is the site/panel title in the Customizer */
    314                                         echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">' . esc_html( $this->title ) . '</strong>' );
     363                                        echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' );
    315364                                ?></span>
    316365                        </div>
    317                         <?php if ( ! empty( $this->description ) ) : ?>
     366                        <# if ( data.description ) { #>
    318367                                <div class="accordion-section-content description">
    319                                         <?php echo $this->description; ?>
     368                                        {{{ data.description }}}
    320369                                </div>
    321                         <?php endif; ?>
     370                        <# } #>
    322371                </li>
    323372                <?php
    324373        }
  • src/wp-includes/class-wp-customize-section.php

     
    213213         * @return array The array to be exported to the client as JSON.
    214214         */
    215215        public function json() {
    216                 $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel', 'type' ) );
     216                if ( ! $this->check_capabilities() ) {
     217                        return;
     218                }
     219
     220                $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'panel', 'type' ) );
    217221                $array['content'] = $this->get_content();
    218222                $array['active'] = $this->active();
    219223                $array['instanceNumber'] = $this->instance_number;
     
    241245        }
    242246
    243247        /**
    244          * Get the section's content template for insertion into the Customizer pane.
     248         * Get the section's content for insertion into the Customizer pane.
    245249         *
    246250         * @since 4.1.0
    247251         *
     
    287291        }
    288292
    289293        /**
    290          * Render the section, and the controls that have been added to it.
     294         * Render the section UI in a subclass.
    291295         *
     296         * Sections are now rendered in JS by default, see {@see WP_Customize_Section::print_template()}.
     297         *
    292298         * @since 3.4.0
    293299         */
    294         protected function render() {
    295                 $classes = 'accordion-section control-section control-section-' . $this->type;
     300        protected function render() {}
     301
     302        /**
     303         * Render the section's JS template.
     304         *
     305         * This function is only run for section types that have been registered with
     306         * {@see WP_Customize_Manager::register_section_type()}.
     307         *
     308         * @since 4.2.0
     309         */
     310        public function print_template() {
     311        ?>
     312        <script type="text/html" id="tmpl-customize-section-<?php echo $this->type; ?>">
     313                        <?php $this->render_template(); ?>
     314        </script>
     315        <?php
     316        }
     317
     318        /**
     319         * An Underscore (JS) template for rendering this section.
     320         *
     321         * Class variables for this section class are available in the `data` JS object;
     322         * export custom variables by overriding {@see WP_Customize_Section::json()}.
     323         *
     324         * @see WP_Customize_Section::print_template()
     325         *
     326         * @since 4.2.0
     327         */
     328        protected function render_template() {
    296329                ?>
    297                 <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
     330                <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
    298331                        <h3 class="accordion-section-title" tabindex="0">
    299                                 <?php echo esc_html( $this->title ); ?>
     332                                {{ data.title }}
    300333                                <span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span>
    301334                        </h3>
    302335                        <ul class="accordion-section-content">
    303                                 <?php if ( ! empty( $this->description ) ) : ?>
     336                                <# if ( data.description ) { #>
    304337                                        <li class="customize-section-description-container">
    305                                                 <p class="description customize-section-description"><?php echo $this->description; ?></p>
     338                                                <p class="description customize-section-description">{{{ data.description }}}</p>
    306339                                        </li>
    307                                 <?php endif; ?>
     340                                <# } #>
    308341                        </ul>
    309342                </li>
    310343                <?php