class-twentytwenty-customize.php 14 KB

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