diff --git src/wp-admin/customize.php src/wp-admin/customize.php
index 178db28..4195a29 100644
|
|
do_action( 'customize_controls_print_scripts' ); |
184 | 184 | <div id="customize-preview" class="wp-full-overlay-main"></div> |
185 | 185 | <?php |
186 | 186 | |
187 | | // Render control templates. |
| 187 | // Render Panel, Section, and Control templates. |
| 188 | $wp_customize->render_panel_templates(); |
| 189 | $wp_customize->render_section_templates(); |
188 | 190 | $wp_customize->render_control_templates(); |
189 | 191 | |
190 | 192 | /** |
… |
… |
do_action( 'customize_controls_print_scripts' ); |
268 | 270 | |
269 | 271 | // Prepare Customize Setting objects to pass to JavaScript. |
270 | 272 | foreach ( $wp_customize->settings() as $id => $setting ) { |
271 | | $settings['settings'][ $id ] = array( |
272 | | 'value' => $setting->js_value(), |
273 | | 'transport' => $setting->transport, |
274 | | ); |
| 273 | if ( $setting->check_capabilities() ) { |
| 274 | $settings['settings'][ $id ] = array( |
| 275 | 'value' => $setting->js_value(), |
| 276 | 'transport' => $setting->transport, |
| 277 | ); |
| 278 | } |
275 | 279 | } |
276 | 280 | |
277 | 281 | // Prepare Customize Control objects to pass to JavaScript. |
278 | 282 | foreach ( $wp_customize->controls() as $id => $control ) { |
279 | | $settings['controls'][ $id ] = $control->json(); |
| 283 | if ( $control->check_capabilities() ) { |
| 284 | $settings['controls'][ $id ] = $control->json(); |
| 285 | } |
280 | 286 | } |
281 | 287 | |
282 | 288 | // Prepare Customize Section objects to pass to JavaScript. |
283 | 289 | foreach ( $wp_customize->sections() as $id => $section ) { |
284 | | $settings['sections'][ $id ] = $section->json(); |
| 290 | if ( $section->check_capabilities() ) { |
| 291 | $settings['sections'][ $id ] = $section->json(); |
| 292 | } |
285 | 293 | } |
286 | 294 | |
287 | 295 | // Prepare Customize Panel objects to pass to JavaScript. |
288 | | foreach ( $wp_customize->panels() as $id => $panel ) { |
289 | | $settings['panels'][ $id ] = $panel->json(); |
290 | | foreach ( $panel->sections as $section_id => $section ) { |
291 | | $settings['sections'][ $section_id ] = $section->json(); |
| 296 | foreach ( $wp_customize->panels() as $panel_id => $panel ) { |
| 297 | if ( $panel->check_capabilities() ) { |
| 298 | $settings['panels'][ $panel_id ] = $panel->json(); |
| 299 | foreach ( $panel->sections as $section_id => $section ) { |
| 300 | if ( $section->check_capabilities() ) { |
| 301 | $settings['sections'][ $section_id ] = $section->json(); |
| 302 | } |
| 303 | } |
292 | 304 | } |
293 | 305 | } |
294 | 306 | |
diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
index 7c4a631..a52a164 100644
|
|
|
149 | 149 | Container = api.Class.extend({ |
150 | 150 | defaultActiveArguments: { duration: 'fast', completeCallback: $.noop }, |
151 | 151 | defaultExpandedArguments: { duration: 'fast', completeCallback: $.noop }, |
| 152 | containerType: 'container', |
152 | 153 | |
153 | 154 | /** |
154 | 155 | * @since 4.1.0 |
… |
… |
|
161 | 162 | container.id = id; |
162 | 163 | container.params = {}; |
163 | 164 | $.extend( container, options || {} ); |
| 165 | container.templateSelector = 'customize-' + container.containerType + '-' + container.params.type; |
164 | 166 | container.container = $( container.params.content ); |
| 167 | if ( 0 === container.container.length ) { |
| 168 | container.container = $( container.getContainer() ); |
| 169 | } |
165 | 170 | |
166 | 171 | container.deferred = { |
167 | 172 | embedded: new $.Deferred() |
… |
… |
|
348 | 353 | * Bring the container into view and then expand this and bring it into view |
349 | 354 | * @param {Object} [params] |
350 | 355 | */ |
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 | } |
352 | 376 | }); |
353 | 377 | |
354 | 378 | /** |
… |
… |
|
358 | 382 | * @augments wp.customize.Class |
359 | 383 | */ |
360 | 384 | api.Section = Container.extend({ |
| 385 | containerType: 'section', |
361 | 386 | |
362 | 387 | /** |
363 | 388 | * @since 4.1.0 |
… |
… |
|
527 | 552 | * @augments wp.customize.Class |
528 | 553 | */ |
529 | 554 | api.Panel = Container.extend({ |
| 555 | containerType: 'panel', |
| 556 | |
530 | 557 | /** |
531 | 558 | * @since 4.1.0 |
532 | 559 | * |
… |
… |
|
553 | 580 | |
554 | 581 | if ( ! panel.container.parent().is( parentContainer ) ) { |
555 | 582 | parentContainer.append( panel.container ); |
| 583 | panel.renderContent(); |
556 | 584 | } |
557 | 585 | panel.deferred.embedded.resolve(); |
558 | 586 | }, |
… |
… |
|
575 | 603 | } |
576 | 604 | }); |
577 | 605 | |
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 ) { |
581 | 607 | if ( api.utils.isKeydownButNotEnterEvent( event ) ) { |
582 | 608 | return; |
583 | 609 | } |
584 | 610 | event.preventDefault(); // Keep this AFTER the key filter above |
585 | 611 | |
| 612 | meta = panel.container.find( '.panel-meta' ); |
586 | 613 | if ( meta.hasClass( 'cannot-expand' ) ) { |
587 | 614 | return; |
588 | 615 | } |
… |
… |
|
704 | 731 | panelTitle.focus(); |
705 | 732 | container.scrollTop( 0 ); |
706 | 733 | } |
| 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 | } |
707 | 754 | } |
708 | 755 | }); |
709 | 756 | |
diff --git src/wp-includes/class-wp-customize-control.php src/wp-includes/class-wp-customize-control.php
index 8e7a3c5..81cc274 100644
|
|
class WP_Customize_Control { |
515 | 515 | * @since 4.1.0 |
516 | 516 | */ |
517 | 517 | 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 |
| 518 | ?> |
| 519 | <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content"> |
| 520 | <?php $this->content_template(); ?> |
| 521 | </script> |
| 522 | <?php |
523 | 523 | } |
524 | 524 | |
525 | 525 | /** |
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
index b695271..6c9ce4f 100644
|
|
final class WP_Customize_Manager { |
54 | 54 | protected $customized; |
55 | 55 | |
56 | 56 | /** |
57 | | * Controls that may be rendered from JS templates. |
| 57 | * Panel types that may be rendered from JS templates. |
| 58 | * |
| 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. |
58 | 76 | * |
59 | 77 | * @since 4.1.0 |
60 | 78 | * @access protected |
… |
… |
final class WP_Customize_Manager { |
513 | 531 | } |
514 | 532 | |
515 | 533 | foreach ( $this->settings as $id => $setting ) { |
516 | | $settings['values'][ $id ] = $setting->js_value(); |
| 534 | if ( $setting->check_capabilities() ) { |
| 535 | $settings['values'][ $id ] = $setting->js_value(); |
| 536 | } |
517 | 537 | } |
518 | | foreach ( $this->panels as $id => $panel ) { |
519 | | $settings['activePanels'][ $id ] = $panel->active(); |
520 | | foreach ( $panel->sections as $id => $section ) { |
521 | | $settings['activeSections'][ $id ] = $section->active(); |
| 538 | foreach ( $this->panels as $panel_id => $panel ) { |
| 539 | if ( $panel->check_capabilities() ) { |
| 540 | $settings['activePanels'][ $panel_id ] = $panel->active(); |
| 541 | foreach ( $panel->sections as $section_id => $section ) { |
| 542 | if ( $section->check_capabilities() ) { |
| 543 | $settings['activeSections'][ $section_id ] = $section->active(); |
| 544 | } |
| 545 | } |
522 | 546 | } |
523 | 547 | } |
524 | 548 | foreach ( $this->sections as $id => $section ) { |
525 | | $settings['activeSections'][ $id ] = $section->active(); |
| 549 | if ( $section->check_capabilities() ) { |
| 550 | $settings['activeSections'][ $id ] = $section->active(); |
| 551 | } |
526 | 552 | } |
527 | 553 | foreach ( $this->controls as $id => $control ) { |
528 | | $settings['activeControls'][ $id ] = $control->active(); |
| 554 | if ( $control->check_capabilities() ) { |
| 555 | $settings['activeControls'][ $id ] = $control->active(); |
| 556 | } |
529 | 557 | } |
530 | 558 | |
531 | 559 | ?> |
… |
… |
final class WP_Customize_Manager { |
774 | 802 | } |
775 | 803 | |
776 | 804 | /** |
| 805 | * Register a customize panel type. |
| 806 | * |
| 807 | * Registered types are eligible to be rendered via JS and created dynamically. |
| 808 | * |
| 809 | * @since 4.2.0 |
| 810 | * @access public |
| 811 | * |
| 812 | * @param string $panel Name of a custom panel which is a subclass of |
| 813 | * {@see WP_Customize_Panel}. |
| 814 | */ |
| 815 | public function register_panel_type( $panel ) { |
| 816 | $this->registered_panel_types[] = $panel; |
| 817 | } |
| 818 | |
| 819 | /** |
| 820 | * Render JS templates for all registered panel types. |
| 821 | * |
| 822 | * @since 4.2.0 |
| 823 | * @access public |
| 824 | */ |
| 825 | public function render_panel_templates() { |
| 826 | foreach ( $this->registered_panel_types as $panel_type ) { |
| 827 | $panel = new $panel_type( $this, 'temp', array() ); |
| 828 | $panel->print_template(); |
| 829 | } |
| 830 | } |
| 831 | |
| 832 | /** |
777 | 833 | * Add a customize section. |
778 | 834 | * |
779 | 835 | * @since 3.4.0 |
… |
… |
final class WP_Customize_Manager { |
815 | 871 | } |
816 | 872 | |
817 | 873 | /** |
| 874 | * Register a customize section type. |
| 875 | * |
| 876 | * Registered types are eligible to be rendered via JS and created dynamically. |
| 877 | * |
| 878 | * @since 4.2.0 |
| 879 | * @access public |
| 880 | * |
| 881 | * @param string $section Name of a custom section which is a subclass of |
| 882 | * {@see WP_Customize_Section}. |
| 883 | */ |
| 884 | public function register_section_type( $section ) { |
| 885 | $this->registered_section_types[] = $section; |
| 886 | } |
| 887 | |
| 888 | /** |
| 889 | * Render JS templates for all registered section types. |
| 890 | * |
| 891 | * @since 4.2.0 |
| 892 | * @access public |
| 893 | */ |
| 894 | public function render_section_templates() { |
| 895 | foreach ( $this->registered_section_types as $section_type ) { |
| 896 | $section = new $section_type( $this, 'temp', array() ); |
| 897 | $section->print_template(); |
| 898 | } |
| 899 | } |
| 900 | |
| 901 | /** |
818 | 902 | * Add a customize control. |
819 | 903 | * |
820 | 904 | * @since 3.4.0 |
… |
… |
final class WP_Customize_Manager { |
985 | 1069 | */ |
986 | 1070 | public function register_controls() { |
987 | 1071 | |
988 | | /* Control Types (custom control classes) */ |
| 1072 | /* Panel, Section, and Control Types */ |
| 1073 | $this->register_panel_type( 'WP_Customize_Panel' ); |
| 1074 | $this->register_section_type( 'WP_Customize_Section' ); |
| 1075 | $this->register_section_type( 'WP_Customize_Sidebar_Section' ); |
989 | 1076 | $this->register_control_type( 'WP_Customize_Color_Control' ); |
990 | 1077 | $this->register_control_type( 'WP_Customize_Upload_Control' ); |
991 | 1078 | $this->register_control_type( 'WP_Customize_Image_Control' ); |
diff --git src/wp-includes/class-wp-customize-panel.php src/wp-includes/class-wp-customize-panel.php
index eed0572..a76be68 100644
|
|
class WP_Customize_Panel { |
204 | 204 | * @return array The array to be exported to the client as JSON. |
205 | 205 | */ |
206 | 206 | public function json() { |
207 | | $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'type' ) ); |
| 207 | $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'type' ) ); |
208 | 208 | $array['content'] = $this->get_content(); |
209 | 209 | $array['active'] = $this->active(); |
210 | 210 | $array['instanceNumber'] = $this->instance_number; |
… |
… |
class WP_Customize_Panel { |
279 | 279 | } |
280 | 280 | |
281 | 281 | /** |
282 | | * Render the panel container, and then its contents. |
| 282 | * Render the panel container, and then its contents (via `this->render_content()`) in a subclass. |
| 283 | * |
| 284 | * Panel containers are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}. |
283 | 285 | * |
284 | 286 | * @since 4.0.0 |
285 | 287 | * @access protected |
286 | 288 | */ |
287 | | protected function render() { |
288 | | $classes = 'accordion-section control-section control-panel control-panel-' . $this->type; |
| 289 | protected function render() {} |
| 290 | |
| 291 | /** |
| 292 | * Render the panel UI in a subclass. |
| 293 | * |
| 294 | * Panel contents are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}. |
| 295 | * |
| 296 | * @since 4.1.0 |
| 297 | * @access protected |
| 298 | */ |
| 299 | protected function render_content() {} |
| 300 | |
| 301 | /** |
| 302 | * Render the panel's JS templates. |
| 303 | * |
| 304 | * This function is only run for panel types that have been registered with |
| 305 | * {@see WP_Customize_Manager::register_panel_type()}. |
| 306 | * |
| 307 | * @since 4.2.0 |
| 308 | */ |
| 309 | public function print_template() { |
289 | 310 | ?> |
290 | | <li id="accordion-panel-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>"> |
| 311 | <script type="text/html" id="tmpl-customize-panel-<?php echo $this->type; ?>-content"> |
| 312 | <?php $this->content_template(); ?> |
| 313 | </script> |
| 314 | <script type="text/html" id="tmpl-customize-panel-<?php echo $this->type; ?>"> |
| 315 | <?php $this->render_template(); ?> |
| 316 | </script> |
| 317 | <?php |
| 318 | } |
| 319 | |
| 320 | /** |
| 321 | * An Underscore (JS) template for rendering this panel's container. |
| 322 | * |
| 323 | * Class variables for this panel class are available in the `data` JS object; |
| 324 | * export custom variables by overriding {@see WP_Customize_Panel::json()}. |
| 325 | * |
| 326 | * @see WP_Customize_Panel::print_template() |
| 327 | * |
| 328 | * @since 4.2.0 |
| 329 | */ |
| 330 | protected function render_template() { |
| 331 | ?> |
| 332 | <li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}"> |
291 | 333 | <h3 class="accordion-section-title" tabindex="0"> |
292 | | <?php echo esc_html( $this->title ); ?> |
| 334 | {{ data.title }} |
293 | 335 | <span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span> |
294 | 336 | </h3> |
295 | | <ul class="accordion-sub-container control-panel-content"> |
296 | | <?php $this->render_content(); ?> |
297 | | </ul> |
| 337 | <ul class="accordion-sub-container control-panel-content"></ul> |
298 | 338 | </li> |
299 | 339 | <?php |
300 | 340 | } |
301 | 341 | |
302 | 342 | /** |
303 | | * Render the sections that have been added to the panel. |
| 343 | * An Underscore (JS) template for this panel's content (but not its container). |
304 | 344 | * |
305 | | * @since 4.1.0 |
306 | | * @access protected |
| 345 | * Class variables for this panel class are available in the `data` JS object; |
| 346 | * export custom variables by overriding {@see WP_Customize_Panel::json()}. |
| 347 | * |
| 348 | * @see WP_Customize_Panel::print_template() |
| 349 | * |
| 350 | * @since 4.2.0 |
307 | 351 | */ |
308 | | protected function render_content() { |
| 352 | protected function content_template() { |
309 | 353 | ?> |
310 | | <li class="panel-meta accordion-section control-section<?php if ( empty( $this->description ) ) { echo ' cannot-expand'; } ?>"> |
| 354 | <li class="panel-meta accordion-section control-section<# if ( ! data.description ) { #> cannot-expand<# } #>"> |
311 | 355 | <div class="accordion-section-title" tabindex="0"> |
312 | 356 | <span class="preview-notice"><?php |
313 | 357 | /* 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>' ); |
| 358 | echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' ); |
315 | 359 | ?></span> |
316 | 360 | </div> |
317 | | <?php if ( ! empty( $this->description ) ) : ?> |
| 361 | <# if ( data.description ) { #> |
318 | 362 | <div class="accordion-section-content description"> |
319 | | <?php echo $this->description; ?> |
| 363 | {{{ data.description }}} |
320 | 364 | </div> |
321 | | <?php endif; ?> |
| 365 | <# } #> |
322 | 366 | </li> |
323 | 367 | <?php |
324 | 368 | } |
diff --git src/wp-includes/class-wp-customize-section.php src/wp-includes/class-wp-customize-section.php
index 7d65689..ac7117e 100644
|
|
class WP_Customize_Section { |
213 | 213 | * @return array The array to be exported to the client as JSON. |
214 | 214 | */ |
215 | 215 | public function json() { |
216 | | $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel', 'type' ) ); |
| 216 | $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'panel', 'type' ) ); |
217 | 217 | $array['content'] = $this->get_content(); |
218 | 218 | $array['active'] = $this->active(); |
219 | 219 | $array['instanceNumber'] = $this->instance_number; |
… |
… |
class WP_Customize_Section { |
241 | 241 | } |
242 | 242 | |
243 | 243 | /** |
244 | | * Get the section's content template for insertion into the Customizer pane. |
| 244 | * Get the section's content for insertion into the Customizer pane. |
245 | 245 | * |
246 | 246 | * @since 4.1.0 |
247 | 247 | * |
… |
… |
class WP_Customize_Section { |
287 | 287 | } |
288 | 288 | |
289 | 289 | /** |
290 | | * Render the section, and the controls that have been added to it. |
| 290 | * Render the section UI in a subclass. |
| 291 | * |
| 292 | * Sections are now rendered in JS by default, see {@see WP_Customize_Section::print_template()}. |
291 | 293 | * |
292 | 294 | * @since 3.4.0 |
293 | 295 | */ |
294 | | protected function render() { |
295 | | $classes = 'accordion-section control-section control-section-' . $this->type; |
| 296 | protected function render() {} |
| 297 | |
| 298 | /** |
| 299 | * Render the section's JS template. |
| 300 | * |
| 301 | * This function is only run for section types that have been registered with |
| 302 | * {@see WP_Customize_Manager::register_section_type()}. |
| 303 | * |
| 304 | * @since 4.2.0 |
| 305 | */ |
| 306 | public function print_template() { |
| 307 | ?> |
| 308 | <script type="text/html" id="tmpl-customize-section-<?php echo $this->type; ?>"> |
| 309 | <?php $this->render_template(); ?> |
| 310 | </script> |
| 311 | <?php |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * An Underscore (JS) template for rendering this section. |
| 316 | * |
| 317 | * Class variables for this section class are available in the `data` JS object; |
| 318 | * export custom variables by overriding {@see WP_Customize_Section::json()}. |
| 319 | * |
| 320 | * @see WP_Customize_Section::print_template() |
| 321 | * |
| 322 | * @since 4.2.0 |
| 323 | */ |
| 324 | protected function render_template() { |
296 | 325 | ?> |
297 | | <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>"> |
| 326 | <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> |
298 | 327 | <h3 class="accordion-section-title" tabindex="0"> |
299 | | <?php echo esc_html( $this->title ); ?> |
| 328 | {{ data.title }} |
300 | 329 | <span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span> |
301 | 330 | </h3> |
302 | 331 | <ul class="accordion-section-content"> |
303 | | <?php if ( ! empty( $this->description ) ) : ?> |
| 332 | <# if ( data.description ) { #> |
304 | 333 | <li class="customize-section-description-container"> |
305 | | <p class="description customize-section-description"><?php echo $this->description; ?></p> |
| 334 | <p class="description customize-section-description">{{{ data.description }}}</p> |
306 | 335 | </li> |
307 | | <?php endif; ?> |
| 336 | <# } #> |
308 | 337 | </ul> |
309 | 338 | </li> |
310 | 339 | <?php |