class-twentytwenty-customize.php (14593B)
1 <?php 2 /** 3 * Customizer settings for this theme. 4 * 5 * @package WordPress 6 * @subpackage Twenty_Twenty 7 * @since Twenty Twenty 1.0 8 */ 9 10 if ( ! class_exists( 'TwentyTwenty_Customize' ) ) { 11 /** 12 * CUSTOMIZER SETTINGS 13 * 14 * @since Twenty Twenty 1.0 15 */ 16 class TwentyTwenty_Customize { 17 18 /** 19 * Register customizer options. 20 * 21 * @since Twenty Twenty 1.0 22 * 23 * @param WP_Customize_Manager $wp_customize Theme Customizer object. 24 */ 25 public static function register( $wp_customize ) { 26 27 /** 28 * Site Title & Description. 29 * */ 30 $wp_customize->get_setting( 'blogname' )->transport = 'postMessage'; 31 $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; 32 33 $wp_customize->selective_refresh->add_partial( 34 'blogname', 35 array( 36 'selector' => '.site-title a', 37 'render_callback' => 'twentytwenty_customize_partial_blogname', 38 ) 39 ); 40 41 $wp_customize->selective_refresh->add_partial( 42 'blogdescription', 43 array( 44 'selector' => '.site-description', 45 'render_callback' => 'twentytwenty_customize_partial_blogdescription', 46 ) 47 ); 48 49 $wp_customize->selective_refresh->add_partial( 50 'custom_logo', 51 array( 52 'selector' => '.header-titles [class*=site-]:not(.site-description)', 53 'render_callback' => 'twentytwenty_customize_partial_site_logo', 54 ) 55 ); 56 57 $wp_customize->selective_refresh->add_partial( 58 'retina_logo', 59 array( 60 'selector' => '.header-titles [class*=site-]:not(.site-description)', 61 'render_callback' => 'twentytwenty_customize_partial_site_logo', 62 ) 63 ); 64 65 /** 66 * Site Identity 67 */ 68 69 /* 2X Header Logo ---------------- */ 70 $wp_customize->add_setting( 71 'retina_logo', 72 array( 73 'capability' => 'edit_theme_options', 74 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 75 'transport' => 'postMessage', 76 ) 77 ); 78 79 $wp_customize->add_control( 80 'retina_logo', 81 array( 82 'type' => 'checkbox', 83 'section' => 'title_tagline', 84 'priority' => 10, 85 'label' => __( 'Retina logo', 'twentytwenty' ), 86 'description' => __( 'Scales the logo to half its uploaded size, making it sharp on high-res screens.', 'twentytwenty' ), 87 ) 88 ); 89 90 // Header & Footer Background Color. 91 $wp_customize->add_setting( 92 'header_footer_background_color', 93 array( 94 'default' => '#ffffff', 95 'sanitize_callback' => 'sanitize_hex_color', 96 'transport' => 'postMessage', 97 ) 98 ); 99 100 $wp_customize->add_control( 101 new WP_Customize_Color_Control( 102 $wp_customize, 103 'header_footer_background_color', 104 array( 105 'label' => __( 'Header & Footer Background Color', 'twentytwenty' ), 106 'section' => 'colors', 107 ) 108 ) 109 ); 110 111 // Enable picking an accent color. 112 $wp_customize->add_setting( 113 'accent_hue_active', 114 array( 115 'capability' => 'edit_theme_options', 116 'sanitize_callback' => array( __CLASS__, 'sanitize_select' ), 117 'transport' => 'postMessage', 118 'default' => 'default', 119 ) 120 ); 121 122 $wp_customize->add_control( 123 'accent_hue_active', 124 array( 125 'type' => 'radio', 126 'section' => 'colors', 127 'label' => __( 'Primary Color', 'twentytwenty' ), 128 'choices' => array( 129 'default' => _x( 'Default', 'color', 'twentytwenty' ), 130 'custom' => _x( 'Custom', 'color', 'twentytwenty' ), 131 ), 132 ) 133 ); 134 135 /** 136 * Implementation for the accent color. 137 * This is different to all other color options because of the accessibility enhancements. 138 * The control is a hue-only colorpicker, and there is a separate setting that holds values 139 * for other colors calculated based on the selected hue and various background-colors on the page. 140 * 141 * @since Twenty Twenty 1.0 142 */ 143 144 // Add the setting for the hue colorpicker. 145 $wp_customize->add_setting( 146 'accent_hue', 147 array( 148 'default' => 344, 149 'type' => 'theme_mod', 150 'sanitize_callback' => 'absint', 151 'transport' => 'postMessage', 152 ) 153 ); 154 155 // Add setting to hold colors derived from the accent hue. 156 $wp_customize->add_setting( 157 'accent_accessible_colors', 158 array( 159 'default' => array( 160 'content' => array( 161 'text' => '#000000', 162 'accent' => '#cd2653', 163 'secondary' => '#6d6d6d', 164 'borders' => '#dcd7ca', 165 ), 166 'header-footer' => array( 167 'text' => '#000000', 168 'accent' => '#cd2653', 169 'secondary' => '#6d6d6d', 170 'borders' => '#dcd7ca', 171 ), 172 ), 173 'type' => 'theme_mod', 174 'transport' => 'postMessage', 175 'sanitize_callback' => array( __CLASS__, 'sanitize_accent_accessible_colors' ), 176 ) 177 ); 178 179 // Add the hue-only colorpicker for the accent color. 180 $wp_customize->add_control( 181 new WP_Customize_Color_Control( 182 $wp_customize, 183 'accent_hue', 184 array( 185 'section' => 'colors', 186 'settings' => 'accent_hue', 187 'description' => __( 'Apply a custom color for links, buttons, featured images.', 'twentytwenty' ), 188 'mode' => 'hue', 189 'active_callback' => function() use ( $wp_customize ) { 190 return ( 'custom' === $wp_customize->get_setting( 'accent_hue_active' )->value() ); 191 }, 192 ) 193 ) 194 ); 195 196 // Update background color with postMessage, so inline CSS output is updated as well. 197 $wp_customize->get_setting( 'background_color' )->transport = 'postMessage'; 198 199 /** 200 * Theme Options 201 */ 202 203 $wp_customize->add_section( 204 'options', 205 array( 206 'title' => __( 'Theme Options', 'twentytwenty' ), 207 'priority' => 40, 208 'capability' => 'edit_theme_options', 209 ) 210 ); 211 212 /* Enable Header Search ----------------------------------------------- */ 213 214 $wp_customize->add_setting( 215 'enable_header_search', 216 array( 217 'capability' => 'edit_theme_options', 218 'default' => true, 219 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 220 ) 221 ); 222 223 $wp_customize->add_control( 224 'enable_header_search', 225 array( 226 'type' => 'checkbox', 227 'section' => 'options', 228 'priority' => 10, 229 'label' => __( 'Show search in header', 'twentytwenty' ), 230 ) 231 ); 232 233 /* Show author bio ---------------------------------------------------- */ 234 235 $wp_customize->add_setting( 236 'show_author_bio', 237 array( 238 'capability' => 'edit_theme_options', 239 'default' => true, 240 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 241 ) 242 ); 243 244 $wp_customize->add_control( 245 'show_author_bio', 246 array( 247 'type' => 'checkbox', 248 'section' => 'options', 249 'priority' => 10, 250 'label' => __( 'Show author bio', 'twentytwenty' ), 251 ) 252 ); 253 254 /* Display full content or excerpts on the blog and archives --------- */ 255 256 $wp_customize->add_setting( 257 'blog_content', 258 array( 259 'capability' => 'edit_theme_options', 260 'default' => 'full', 261 'sanitize_callback' => array( __CLASS__, 'sanitize_select' ), 262 ) 263 ); 264 265 $wp_customize->add_control( 266 'blog_content', 267 array( 268 'type' => 'radio', 269 'section' => 'options', 270 'priority' => 10, 271 'label' => __( 'On archive pages, posts show:', 'twentytwenty' ), 272 'choices' => array( 273 'full' => __( 'Full text', 'twentytwenty' ), 274 'summary' => __( 'Summary', 'twentytwenty' ), 275 ), 276 ) 277 ); 278 279 /** 280 * Template: Cover Template. 281 */ 282 $wp_customize->add_section( 283 'cover_template_options', 284 array( 285 'title' => __( 'Cover Template', 'twentytwenty' ), 286 'capability' => 'edit_theme_options', 287 'description' => __( 'Settings for the "Cover Template" page template. Add a featured image to use as background.', 'twentytwenty' ), 288 'priority' => 42, 289 ) 290 ); 291 292 /* Overlay Fixed Background ------ */ 293 294 $wp_customize->add_setting( 295 'cover_template_fixed_background', 296 array( 297 'capability' => 'edit_theme_options', 298 'default' => true, 299 'sanitize_callback' => array( __CLASS__, 'sanitize_checkbox' ), 300 'transport' => 'postMessage', 301 ) 302 ); 303 304 $wp_customize->add_control( 305 'cover_template_fixed_background', 306 array( 307 'type' => 'checkbox', 308 'section' => 'cover_template_options', 309 'label' => __( 'Fixed Background Image', 'twentytwenty' ), 310 'description' => __( 'Creates a parallax effect when the visitor scrolls.', 'twentytwenty' ), 311 ) 312 ); 313 314 $wp_customize->selective_refresh->add_partial( 315 'cover_template_fixed_background', 316 array( 317 'selector' => '.cover-header', 318 'type' => 'cover_fixed', 319 ) 320 ); 321 322 /* Separator --------------------- */ 323 324 $wp_customize->add_setting( 325 'cover_template_separator_1', 326 array( 327 'sanitize_callback' => 'wp_filter_nohtml_kses', 328 ) 329 ); 330 331 $wp_customize->add_control( 332 new TwentyTwenty_Separator_Control( 333 $wp_customize, 334 'cover_template_separator_1', 335 array( 336 'section' => 'cover_template_options', 337 ) 338 ) 339 ); 340 341 /* Overlay Background Color ------ */ 342 343 $wp_customize->add_setting( 344 'cover_template_overlay_background_color', 345 array( 346 'default' => twentytwenty_get_color_for_area( 'content', 'accent' ), 347 'sanitize_callback' => 'sanitize_hex_color', 348 ) 349 ); 350 351 $wp_customize->add_control( 352 new WP_Customize_Color_Control( 353 $wp_customize, 354 'cover_template_overlay_background_color', 355 array( 356 'label' => __( 'Overlay Background Color', 'twentytwenty' ), 357 'description' => __( 'The color used for the overlay. Defaults to the accent color.', 'twentytwenty' ), 358 'section' => 'cover_template_options', 359 ) 360 ) 361 ); 362 363 /* Overlay Text Color ------------ */ 364 365 $wp_customize->add_setting( 366 'cover_template_overlay_text_color', 367 array( 368 'default' => '#ffffff', 369 'sanitize_callback' => 'sanitize_hex_color', 370 ) 371 ); 372 373 $wp_customize->add_control( 374 new WP_Customize_Color_Control( 375 $wp_customize, 376 'cover_template_overlay_text_color', 377 array( 378 'label' => __( 'Overlay Text Color', 'twentytwenty' ), 379 'description' => __( 'The color used for the text in the overlay.', 'twentytwenty' ), 380 'section' => 'cover_template_options', 381 ) 382 ) 383 ); 384 385 /* Overlay Color Opacity --------- */ 386 387 $wp_customize->add_setting( 388 'cover_template_overlay_opacity', 389 array( 390 'default' => 80, 391 'sanitize_callback' => 'absint', 392 'transport' => 'postMessage', 393 ) 394 ); 395 396 $wp_customize->add_control( 397 'cover_template_overlay_opacity', 398 array( 399 'label' => __( 'Overlay Opacity', 'twentytwenty' ), 400 'description' => __( 'Make sure that the contrast is high enough so that the text is readable.', 'twentytwenty' ), 401 'section' => 'cover_template_options', 402 'type' => 'range', 403 'input_attrs' => twentytwenty_customize_opacity_range(), 404 ) 405 ); 406 407 $wp_customize->selective_refresh->add_partial( 408 'cover_template_overlay_opacity', 409 array( 410 'selector' => '.cover-color-overlay', 411 'type' => 'cover_opacity', 412 ) 413 ); 414 } 415 416 /** 417 * Sanitization callback for the "accent_accessible_colors" setting. 418 * 419 * @since Twenty Twenty 1.0 420 * 421 * @param array $value The value we want to sanitize. 422 * @return array Returns sanitized value. Each item in the array gets sanitized separately. 423 */ 424 public static function sanitize_accent_accessible_colors( $value ) { 425 426 // Make sure the value is an array. Do not typecast, use empty array as fallback. 427 $value = is_array( $value ) ? $value : array(); 428 429 // Loop values. 430 foreach ( $value as $area => $values ) { 431 foreach ( $values as $context => $color_val ) { 432 $value[ $area ][ $context ] = sanitize_hex_color( $color_val ); 433 } 434 } 435 436 return $value; 437 } 438 439 /** 440 * Sanitize select. 441 * 442 * @since Twenty Twenty 1.0 443 * 444 * @param string $input The input from the setting. 445 * @param object $setting The selected setting. 446 * @return string The input from the setting or the default setting. 447 */ 448 public static function sanitize_select( $input, $setting ) { 449 $input = sanitize_key( $input ); 450 $choices = $setting->manager->get_control( $setting->id )->choices; 451 return ( array_key_exists( $input, $choices ) ? $input : $setting->default ); 452 } 453 454 /** 455 * Sanitize boolean for checkbox. 456 * 457 * @since Twenty Twenty 1.0 458 * 459 * @param bool $checked Whether or not a box is checked. 460 * @return bool 461 */ 462 public static function sanitize_checkbox( $checked ) { 463 return ( ( isset( $checked ) && true === $checked ) ? true : false ); 464 } 465 466 } 467 468 // Setup the Theme Customizer settings and controls. 469 add_action( 'customize_register', array( 'TwentyTwenty_Customize', 'register' ) ); 470 471 } 472 473 /** 474 * PARTIAL REFRESH FUNCTIONS 475 * */ 476 if ( ! function_exists( 'twentytwenty_customize_partial_blogname' ) ) { 477 /** 478 * Render the site title for the selective refresh partial. 479 * 480 * @since Twenty Twenty 1.0 481 */ 482 function twentytwenty_customize_partial_blogname() { 483 bloginfo( 'name' ); 484 } 485 } 486 487 if ( ! function_exists( 'twentytwenty_customize_partial_blogdescription' ) ) { 488 /** 489 * Render the site description for the selective refresh partial. 490 * 491 * @since Twenty Twenty 1.0 492 */ 493 function twentytwenty_customize_partial_blogdescription() { 494 bloginfo( 'description' ); 495 } 496 } 497 498 if ( ! function_exists( 'twentytwenty_customize_partial_site_logo' ) ) { 499 /** 500 * Render the site logo for the selective refresh partial. 501 * 502 * Doing it this way so we don't have issues with `render_callback`'s arguments. 503 * 504 * @since Twenty Twenty 1.0 505 */ 506 function twentytwenty_customize_partial_site_logo() { 507 twentytwenty_site_logo(); 508 } 509 } 510 511 512 /** 513 * Input attributes for cover overlay opacity option. 514 * 515 * @since Twenty Twenty 1.0 516 * 517 * @return array Array containing attribute names and their values. 518 */ 519 function twentytwenty_customize_opacity_range() { 520 /** 521 * Filters the input attributes for opacity. 522 * 523 * @since Twenty Twenty 1.0 524 * 525 * @param array $attrs { 526 * The attributes. 527 * 528 * @type int $min Minimum value. 529 * @type int $max Maximum value. 530 * @type int $step Interval between numbers. 531 * } 532 */ 533 return apply_filters( 534 'twentytwenty_customize_opacity_range', 535 array( 536 'min' => 0, 537 'max' => 90, 538 'step' => 5, 539 ) 540 ); 541 }