functions.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. <?php
  2. /**
  3. * Functions and definitions
  4. *
  5. * @link https://developer.wordpress.org/themes/basics/theme-functions/
  6. *
  7. * @package WordPress
  8. * @subpackage Twenty_Twenty_One
  9. * @since Twenty Twenty-One 1.0
  10. */
  11. // This theme requires WordPress 5.3 or later.
  12. if ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) {
  13. require get_template_directory() . '/inc/back-compat.php';
  14. }
  15. if ( ! function_exists( 'twenty_twenty_one_setup' ) ) {
  16. /**
  17. * Sets up theme defaults and registers support for various WordPress features.
  18. *
  19. * Note that this function is hooked into the after_setup_theme hook, which
  20. * runs before the init hook. The init hook is too late for some features, such
  21. * as indicating support for post thumbnails.
  22. *
  23. * @since Twenty Twenty-One 1.0
  24. *
  25. * @return void
  26. */
  27. function twenty_twenty_one_setup() {
  28. /*
  29. * Make theme available for translation.
  30. * Translations can be filed in the /languages/ directory.
  31. * If you're building a theme based on Twenty Twenty-One, use a find and replace
  32. * to change 'twentytwentyone' to the name of your theme in all the template files.
  33. */
  34. load_theme_textdomain( 'twentytwentyone', get_template_directory() . '/languages' );
  35. // Add default posts and comments RSS feed links to head.
  36. add_theme_support( 'automatic-feed-links' );
  37. /*
  38. * Let WordPress manage the document title.
  39. * This theme does not use a hard-coded <title> tag in the document head,
  40. * WordPress will provide it for us.
  41. */
  42. add_theme_support( 'title-tag' );
  43. /**
  44. * Add post-formats support.
  45. */
  46. add_theme_support(
  47. 'post-formats',
  48. array(
  49. 'link',
  50. 'aside',
  51. 'gallery',
  52. 'image',
  53. 'quote',
  54. 'status',
  55. 'video',
  56. 'audio',
  57. 'chat',
  58. )
  59. );
  60. /*
  61. * Enable support for Post Thumbnails on posts and pages.
  62. *
  63. * @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
  64. */
  65. add_theme_support( 'post-thumbnails' );
  66. set_post_thumbnail_size( 1568, 9999 );
  67. register_nav_menus(
  68. array(
  69. 'primary' => esc_html__( 'Primary menu', 'twentytwentyone' ),
  70. 'footer' => esc_html__( 'Secondary menu', 'twentytwentyone' ),
  71. )
  72. );
  73. /*
  74. * Switch default core markup for search form, comment form, and comments
  75. * to output valid HTML5.
  76. */
  77. add_theme_support(
  78. 'html5',
  79. array(
  80. 'comment-form',
  81. 'comment-list',
  82. 'gallery',
  83. 'caption',
  84. 'style',
  85. 'script',
  86. 'navigation-widgets',
  87. )
  88. );
  89. /*
  90. * Add support for core custom logo.
  91. *
  92. * @link https://codex.wordpress.org/Theme_Logo
  93. */
  94. $logo_width = 300;
  95. $logo_height = 100;
  96. add_theme_support(
  97. 'custom-logo',
  98. array(
  99. 'height' => $logo_height,
  100. 'width' => $logo_width,
  101. 'flex-width' => true,
  102. 'flex-height' => true,
  103. 'unlink-homepage-logo' => true,
  104. )
  105. );
  106. // Add theme support for selective refresh for widgets.
  107. add_theme_support( 'customize-selective-refresh-widgets' );
  108. // Add support for Block Styles.
  109. add_theme_support( 'wp-block-styles' );
  110. // Add support for full and wide align images.
  111. add_theme_support( 'align-wide' );
  112. // Add support for editor styles.
  113. add_theme_support( 'editor-styles' );
  114. $background_color = get_theme_mod( 'background_color', 'D1E4DD' );
  115. if ( 127 > Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) ) {
  116. add_theme_support( 'dark-editor-style' );
  117. }
  118. $editor_stylesheet_path = './assets/css/style-editor.css';
  119. // Note, the is_IE global variable is defined by WordPress and is used
  120. // to detect if the current browser is internet explorer.
  121. global $is_IE;
  122. if ( $is_IE ) {
  123. $editor_stylesheet_path = './assets/css/ie-editor.css';
  124. }
  125. // Enqueue editor styles.
  126. add_editor_style( $editor_stylesheet_path );
  127. // Add custom editor font sizes.
  128. add_theme_support(
  129. 'editor-font-sizes',
  130. array(
  131. array(
  132. 'name' => esc_html__( 'Extra small', 'twentytwentyone' ),
  133. 'shortName' => esc_html_x( 'XS', 'Font size', 'twentytwentyone' ),
  134. 'size' => 16,
  135. 'slug' => 'extra-small',
  136. ),
  137. array(
  138. 'name' => esc_html__( 'Small', 'twentytwentyone' ),
  139. 'shortName' => esc_html_x( 'S', 'Font size', 'twentytwentyone' ),
  140. 'size' => 18,
  141. 'slug' => 'small',
  142. ),
  143. array(
  144. 'name' => esc_html__( 'Normal', 'twentytwentyone' ),
  145. 'shortName' => esc_html_x( 'M', 'Font size', 'twentytwentyone' ),
  146. 'size' => 20,
  147. 'slug' => 'normal',
  148. ),
  149. array(
  150. 'name' => esc_html__( 'Large', 'twentytwentyone' ),
  151. 'shortName' => esc_html_x( 'L', 'Font size', 'twentytwentyone' ),
  152. 'size' => 24,
  153. 'slug' => 'large',
  154. ),
  155. array(
  156. 'name' => esc_html__( 'Extra large', 'twentytwentyone' ),
  157. 'shortName' => esc_html_x( 'XL', 'Font size', 'twentytwentyone' ),
  158. 'size' => 40,
  159. 'slug' => 'extra-large',
  160. ),
  161. array(
  162. 'name' => esc_html__( 'Huge', 'twentytwentyone' ),
  163. 'shortName' => esc_html_x( 'XXL', 'Font size', 'twentytwentyone' ),
  164. 'size' => 96,
  165. 'slug' => 'huge',
  166. ),
  167. array(
  168. 'name' => esc_html__( 'Gigantic', 'twentytwentyone' ),
  169. 'shortName' => esc_html_x( 'XXXL', 'Font size', 'twentytwentyone' ),
  170. 'size' => 144,
  171. 'slug' => 'gigantic',
  172. ),
  173. )
  174. );
  175. // Custom background color.
  176. add_theme_support(
  177. 'custom-background',
  178. array(
  179. 'default-color' => 'd1e4dd',
  180. )
  181. );
  182. // Editor color palette.
  183. $black = '#000000';
  184. $dark_gray = '#28303D';
  185. $gray = '#39414D';
  186. $green = '#D1E4DD';
  187. $blue = '#D1DFE4';
  188. $purple = '#D1D1E4';
  189. $red = '#E4D1D1';
  190. $orange = '#E4DAD1';
  191. $yellow = '#EEEADD';
  192. $white = '#FFFFFF';
  193. add_theme_support(
  194. 'editor-color-palette',
  195. array(
  196. array(
  197. 'name' => esc_html__( 'Black', 'twentytwentyone' ),
  198. 'slug' => 'black',
  199. 'color' => $black,
  200. ),
  201. array(
  202. 'name' => esc_html__( 'Dark gray', 'twentytwentyone' ),
  203. 'slug' => 'dark-gray',
  204. 'color' => $dark_gray,
  205. ),
  206. array(
  207. 'name' => esc_html__( 'Gray', 'twentytwentyone' ),
  208. 'slug' => 'gray',
  209. 'color' => $gray,
  210. ),
  211. array(
  212. 'name' => esc_html__( 'Green', 'twentytwentyone' ),
  213. 'slug' => 'green',
  214. 'color' => $green,
  215. ),
  216. array(
  217. 'name' => esc_html__( 'Blue', 'twentytwentyone' ),
  218. 'slug' => 'blue',
  219. 'color' => $blue,
  220. ),
  221. array(
  222. 'name' => esc_html__( 'Purple', 'twentytwentyone' ),
  223. 'slug' => 'purple',
  224. 'color' => $purple,
  225. ),
  226. array(
  227. 'name' => esc_html__( 'Red', 'twentytwentyone' ),
  228. 'slug' => 'red',
  229. 'color' => $red,
  230. ),
  231. array(
  232. 'name' => esc_html__( 'Orange', 'twentytwentyone' ),
  233. 'slug' => 'orange',
  234. 'color' => $orange,
  235. ),
  236. array(
  237. 'name' => esc_html__( 'Yellow', 'twentytwentyone' ),
  238. 'slug' => 'yellow',
  239. 'color' => $yellow,
  240. ),
  241. array(
  242. 'name' => esc_html__( 'White', 'twentytwentyone' ),
  243. 'slug' => 'white',
  244. 'color' => $white,
  245. ),
  246. )
  247. );
  248. add_theme_support(
  249. 'editor-gradient-presets',
  250. array(
  251. array(
  252. 'name' => esc_html__( 'Purple to yellow', 'twentytwentyone' ),
  253. 'gradient' => 'linear-gradient(160deg, ' . $purple . ' 0%, ' . $yellow . ' 100%)',
  254. 'slug' => 'purple-to-yellow',
  255. ),
  256. array(
  257. 'name' => esc_html__( 'Yellow to purple', 'twentytwentyone' ),
  258. 'gradient' => 'linear-gradient(160deg, ' . $yellow . ' 0%, ' . $purple . ' 100%)',
  259. 'slug' => 'yellow-to-purple',
  260. ),
  261. array(
  262. 'name' => esc_html__( 'Green to yellow', 'twentytwentyone' ),
  263. 'gradient' => 'linear-gradient(160deg, ' . $green . ' 0%, ' . $yellow . ' 100%)',
  264. 'slug' => 'green-to-yellow',
  265. ),
  266. array(
  267. 'name' => esc_html__( 'Yellow to green', 'twentytwentyone' ),
  268. 'gradient' => 'linear-gradient(160deg, ' . $yellow . ' 0%, ' . $green . ' 100%)',
  269. 'slug' => 'yellow-to-green',
  270. ),
  271. array(
  272. 'name' => esc_html__( 'Red to yellow', 'twentytwentyone' ),
  273. 'gradient' => 'linear-gradient(160deg, ' . $red . ' 0%, ' . $yellow . ' 100%)',
  274. 'slug' => 'red-to-yellow',
  275. ),
  276. array(
  277. 'name' => esc_html__( 'Yellow to red', 'twentytwentyone' ),
  278. 'gradient' => 'linear-gradient(160deg, ' . $yellow . ' 0%, ' . $red . ' 100%)',
  279. 'slug' => 'yellow-to-red',
  280. ),
  281. array(
  282. 'name' => esc_html__( 'Purple to red', 'twentytwentyone' ),
  283. 'gradient' => 'linear-gradient(160deg, ' . $purple . ' 0%, ' . $red . ' 100%)',
  284. 'slug' => 'purple-to-red',
  285. ),
  286. array(
  287. 'name' => esc_html__( 'Red to purple', 'twentytwentyone' ),
  288. 'gradient' => 'linear-gradient(160deg, ' . $red . ' 0%, ' . $purple . ' 100%)',
  289. 'slug' => 'red-to-purple',
  290. ),
  291. )
  292. );
  293. /*
  294. * Adds starter content to highlight the theme on fresh sites.
  295. * This is done conditionally to avoid loading the starter content on every
  296. * page load, as it is a one-off operation only needed once in the customizer.
  297. */
  298. if ( is_customize_preview() ) {
  299. require get_template_directory() . '/inc/starter-content.php';
  300. add_theme_support( 'starter-content', twenty_twenty_one_get_starter_content() );
  301. }
  302. // Add support for responsive embedded content.
  303. add_theme_support( 'responsive-embeds' );
  304. // Add support for custom line height controls.
  305. add_theme_support( 'custom-line-height' );
  306. // Add support for experimental link color control.
  307. add_theme_support( 'experimental-link-color' );
  308. // Add support for experimental cover block spacing.
  309. add_theme_support( 'custom-spacing' );
  310. // Add support for custom units.
  311. // This was removed in WordPress 5.6 but is still required to properly support WP 5.5.
  312. add_theme_support( 'custom-units' );
  313. // Remove feed icon link from legacy RSS widget.
  314. add_filter( 'rss_widget_feed_link', '__return_false' );
  315. }
  316. }
  317. add_action( 'after_setup_theme', 'twenty_twenty_one_setup' );
  318. /**
  319. * Register widget area.
  320. *
  321. * @since Twenty Twenty-One 1.0
  322. *
  323. * @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
  324. *
  325. * @return void
  326. */
  327. function twenty_twenty_one_widgets_init() {
  328. register_sidebar(
  329. array(
  330. 'name' => esc_html__( 'Footer', 'twentytwentyone' ),
  331. 'id' => 'sidebar-1',
  332. 'description' => esc_html__( 'Add widgets here to appear in your footer.', 'twentytwentyone' ),
  333. 'before_widget' => '<section id="%1$s" class="widget %2$s">',
  334. 'after_widget' => '</section>',
  335. 'before_title' => '<h2 class="widget-title">',
  336. 'after_title' => '</h2>',
  337. )
  338. );
  339. }
  340. add_action( 'widgets_init', 'twenty_twenty_one_widgets_init' );
  341. /**
  342. * Set the content width in pixels, based on the theme's design and stylesheet.
  343. *
  344. * Priority 0 to make it available to lower priority callbacks.
  345. *
  346. * @since Twenty Twenty-One 1.0
  347. *
  348. * @global int $content_width Content width.
  349. *
  350. * @return void
  351. */
  352. function twenty_twenty_one_content_width() {
  353. // This variable is intended to be overruled from themes.
  354. // Open WPCS issue: {@link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/1043}.
  355. // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
  356. $GLOBALS['content_width'] = apply_filters( 'twenty_twenty_one_content_width', 750 );
  357. }
  358. add_action( 'after_setup_theme', 'twenty_twenty_one_content_width', 0 );
  359. /**
  360. * Enqueue scripts and styles.
  361. *
  362. * @since Twenty Twenty-One 1.0
  363. *
  364. * @return void
  365. */
  366. function twenty_twenty_one_scripts() {
  367. // Note, the is_IE global variable is defined by WordPress and is used
  368. // to detect if the current browser is internet explorer.
  369. global $is_IE, $wp_scripts;
  370. if ( $is_IE ) {
  371. // If IE 11 or below, use a flattened stylesheet with static values replacing CSS Variables.
  372. wp_enqueue_style( 'twenty-twenty-one-style', get_template_directory_uri() . '/assets/css/ie.css', array(), wp_get_theme()->get( 'Version' ) );
  373. } else {
  374. // If not IE, use the standard stylesheet.
  375. wp_enqueue_style( 'twenty-twenty-one-style', get_template_directory_uri() . '/style.css', array(), wp_get_theme()->get( 'Version' ) );
  376. }
  377. // RTL styles.
  378. wp_style_add_data( 'twenty-twenty-one-style', 'rtl', 'replace' );
  379. // Print styles.
  380. wp_enqueue_style( 'twenty-twenty-one-print-style', get_template_directory_uri() . '/assets/css/print.css', array(), wp_get_theme()->get( 'Version' ), 'print' );
  381. // Threaded comment reply styles.
  382. if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
  383. wp_enqueue_script( 'comment-reply' );
  384. }
  385. // Register the IE11 polyfill file.
  386. wp_register_script(
  387. 'twenty-twenty-one-ie11-polyfills-asset',
  388. get_template_directory_uri() . '/assets/js/polyfills.js',
  389. array(),
  390. wp_get_theme()->get( 'Version' ),
  391. true
  392. );
  393. // Register the IE11 polyfill loader.
  394. wp_register_script(
  395. 'twenty-twenty-one-ie11-polyfills',
  396. null,
  397. array(),
  398. wp_get_theme()->get( 'Version' ),
  399. true
  400. );
  401. wp_add_inline_script(
  402. 'twenty-twenty-one-ie11-polyfills',
  403. wp_get_script_polyfill(
  404. $wp_scripts,
  405. array(
  406. 'Element.prototype.matches && Element.prototype.closest && window.NodeList && NodeList.prototype.forEach' => 'twenty-twenty-one-ie11-polyfills-asset',
  407. )
  408. )
  409. );
  410. // Main navigation scripts.
  411. if ( has_nav_menu( 'primary' ) ) {
  412. wp_enqueue_script(
  413. 'twenty-twenty-one-primary-navigation-script',
  414. get_template_directory_uri() . '/assets/js/primary-navigation.js',
  415. array( 'twenty-twenty-one-ie11-polyfills' ),
  416. wp_get_theme()->get( 'Version' ),
  417. true
  418. );
  419. }
  420. // Responsive embeds script.
  421. wp_enqueue_script(
  422. 'twenty-twenty-one-responsive-embeds-script',
  423. get_template_directory_uri() . '/assets/js/responsive-embeds.js',
  424. array( 'twenty-twenty-one-ie11-polyfills' ),
  425. wp_get_theme()->get( 'Version' ),
  426. true
  427. );
  428. }
  429. add_action( 'wp_enqueue_scripts', 'twenty_twenty_one_scripts' );
  430. /**
  431. * Enqueue block editor script.
  432. *
  433. * @since Twenty Twenty-One 1.0
  434. *
  435. * @return void
  436. */
  437. function twentytwentyone_block_editor_script() {
  438. wp_enqueue_script( 'twentytwentyone-editor', get_theme_file_uri( '/assets/js/editor.js' ), array( 'wp-blocks', 'wp-dom' ), wp_get_theme()->get( 'Version' ), true );
  439. }
  440. add_action( 'enqueue_block_editor_assets', 'twentytwentyone_block_editor_script' );
  441. /**
  442. * Fix skip link focus in IE11.
  443. *
  444. * This does not enqueue the script because it is tiny and because it is only for IE11,
  445. * thus it does not warrant having an entire dedicated blocking script being loaded.
  446. *
  447. * @since Twenty Twenty-One 1.0
  448. *
  449. * @link https://git.io/vWdr2
  450. */
  451. function twenty_twenty_one_skip_link_focus_fix() {
  452. // If SCRIPT_DEBUG is defined and true, print the unminified file.
  453. if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
  454. echo '<script>';
  455. include get_template_directory() . '/assets/js/skip-link-focus-fix.js';
  456. echo '</script>';
  457. } else {
  458. // The following is minified via `npx terser --compress --mangle -- assets/js/skip-link-focus-fix.js`.
  459. ?>
  460. <script>
  461. /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",(function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())}),!1);
  462. </script>
  463. <?php
  464. }
  465. }
  466. add_action( 'wp_print_footer_scripts', 'twenty_twenty_one_skip_link_focus_fix' );
  467. /**
  468. * Enqueue non-latin language styles.
  469. *
  470. * @since Twenty Twenty-One 1.0
  471. *
  472. * @return void
  473. */
  474. function twenty_twenty_one_non_latin_languages() {
  475. $custom_css = twenty_twenty_one_get_non_latin_css( 'front-end' );
  476. if ( $custom_css ) {
  477. wp_add_inline_style( 'twenty-twenty-one-style', $custom_css );
  478. }
  479. }
  480. add_action( 'wp_enqueue_scripts', 'twenty_twenty_one_non_latin_languages' );
  481. // SVG Icons class.
  482. require get_template_directory() . '/classes/class-twenty-twenty-one-svg-icons.php';
  483. // Custom color classes.
  484. require get_template_directory() . '/classes/class-twenty-twenty-one-custom-colors.php';
  485. new Twenty_Twenty_One_Custom_Colors();
  486. // Enhance the theme by hooking into WordPress.
  487. require get_template_directory() . '/inc/template-functions.php';
  488. // Menu functions and filters.
  489. require get_template_directory() . '/inc/menu-functions.php';
  490. // Custom template tags for the theme.
  491. require get_template_directory() . '/inc/template-tags.php';
  492. // Customizer additions.
  493. require get_template_directory() . '/classes/class-twenty-twenty-one-customize.php';
  494. new Twenty_Twenty_One_Customize();
  495. // Block Patterns.
  496. require get_template_directory() . '/inc/block-patterns.php';
  497. // Block Styles.
  498. require get_template_directory() . '/inc/block-styles.php';
  499. // Dark Mode.
  500. require_once get_template_directory() . '/classes/class-twenty-twenty-one-dark-mode.php';
  501. new Twenty_Twenty_One_Dark_Mode();
  502. /**
  503. * Enqueue scripts for the customizer preview.
  504. *
  505. * @since Twenty Twenty-One 1.0
  506. *
  507. * @return void
  508. */
  509. function twentytwentyone_customize_preview_init() {
  510. wp_enqueue_script(
  511. 'twentytwentyone-customize-helpers',
  512. get_theme_file_uri( '/assets/js/customize-helpers.js' ),
  513. array(),
  514. wp_get_theme()->get( 'Version' ),
  515. true
  516. );
  517. wp_enqueue_script(
  518. 'twentytwentyone-customize-preview',
  519. get_theme_file_uri( '/assets/js/customize-preview.js' ),
  520. array( 'customize-preview', 'customize-selective-refresh', 'jquery', 'twentytwentyone-customize-helpers' ),
  521. wp_get_theme()->get( 'Version' ),
  522. true
  523. );
  524. }
  525. add_action( 'customize_preview_init', 'twentytwentyone_customize_preview_init' );
  526. /**
  527. * Enqueue scripts for the customizer.
  528. *
  529. * @since Twenty Twenty-One 1.0
  530. *
  531. * @return void
  532. */
  533. function twentytwentyone_customize_controls_enqueue_scripts() {
  534. wp_enqueue_script(
  535. 'twentytwentyone-customize-helpers',
  536. get_theme_file_uri( '/assets/js/customize-helpers.js' ),
  537. array(),
  538. wp_get_theme()->get( 'Version' ),
  539. true
  540. );
  541. }
  542. add_action( 'customize_controls_enqueue_scripts', 'twentytwentyone_customize_controls_enqueue_scripts' );
  543. /**
  544. * Calculate classes for the main <html> element.
  545. *
  546. * @since Twenty Twenty-One 1.0
  547. *
  548. * @return void
  549. */
  550. function twentytwentyone_the_html_classes() {
  551. /**
  552. * Filters the classes for the main <html> element.
  553. *
  554. * @since Twenty Twenty-One 1.0
  555. *
  556. * @param string The list of classes. Default empty string.
  557. */
  558. $classes = apply_filters( 'twentytwentyone_html_classes', '' );
  559. if ( ! $classes ) {
  560. return;
  561. }
  562. echo 'class="' . esc_attr( $classes ) . '"';
  563. }
  564. /**
  565. * Add "is-IE" class to body if the user is on Internet Explorer.
  566. *
  567. * @since Twenty Twenty-One 1.0
  568. *
  569. * @return void
  570. */
  571. function twentytwentyone_add_ie_class() {
  572. ?>
  573. <script>
  574. if ( -1 !== navigator.userAgent.indexOf( 'MSIE' ) || -1 !== navigator.appVersion.indexOf( 'Trident/' ) ) {
  575. document.body.classList.add( 'is-IE' );
  576. }
  577. </script>
  578. <?php
  579. }
  580. add_action( 'wp_footer', 'twentytwentyone_add_ie_class' );
  581. if ( ! function_exists( 'wp_get_list_item_separator' ) ) :
  582. /**
  583. * Retrieves the list item separator based on the locale.
  584. *
  585. * Added for backward compatibility to support pre-6.0.0 WordPress versions.
  586. *
  587. * @since 6.0.0
  588. */
  589. function wp_get_list_item_separator() {
  590. /* translators: Used between list items, there is a space after the comma. */
  591. return __( ', ', 'twentytwentyone' );
  592. }
  593. endif;