[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-content/themes/twentytwenty/inc/ -> template-tags.php (source)

   1  <?php
   2  /**
   3   * Custom template tags for this theme.
   4   *
   5   * @package WordPress
   6   * @subpackage Twenty_Twenty
   7   * @since Twenty Twenty 1.0
   8   */
   9  
  10  /**
  11   * Table of Contents:
  12   * Logo & Description
  13   * Comments
  14   * Post Meta
  15   * Menus
  16   * Classes
  17   * Archives
  18   * Miscellaneous
  19   */
  20  
  21  /**
  22   * Logo & Description
  23   */
  24  
  25  /**
  26   * Displays the site logo, either text or image.
  27   *
  28   * @since Twenty Twenty 1.0
  29   *
  30   * @param array $args    Arguments for displaying the site logo either as an image or text.
  31   * @param bool  $display Display or return the HTML.
  32   * @return string Compiled HTML based on our arguments.
  33   */
  34  function twentytwenty_site_logo( $args = array(), $display = true ) {
  35      $logo       = get_custom_logo();
  36      $site_title = get_bloginfo( 'name' );
  37      $contents   = '';
  38      $classname  = '';
  39  
  40      $defaults = array(
  41          'logo'        => '%1$s<span class="screen-reader-text">%2$s</span>',
  42          'logo_class'  => 'site-logo',
  43          'title'       => '<a href="%1$s" rel="home">%2$s</a>',
  44          'title_class' => 'site-title',
  45          'home_wrap'   => '<h1 class="%1$s">%2$s</h1>',
  46          'single_wrap' => '<div class="%1$s faux-heading">%2$s</div>',
  47          'condition'   => ( is_front_page() || is_home() ) && ! is_page(),
  48      );
  49  
  50      $args = wp_parse_args( $args, $defaults );
  51  
  52      /**
  53       * Filters the arguments for `twentytwenty_site_logo()`.
  54       *
  55       * @since Twenty Twenty 1.0
  56       *
  57       * @param array $args     Parsed arguments.
  58       * @param array $defaults Function's default arguments.
  59       */
  60      $args = apply_filters( 'twentytwenty_site_logo_args', $args, $defaults );
  61  
  62      if ( has_custom_logo() ) {
  63          $contents  = sprintf( $args['logo'], $logo, esc_html( $site_title ) );
  64          $classname = $args['logo_class'];
  65      } else {
  66          $contents = sprintf( $args['title'], esc_url( get_home_url( null, '/' ) ), esc_html( $site_title ) );
  67          if (
  68              ( is_front_page() || is_home() && ( (int) get_option( 'page_for_posts' ) !== get_queried_object_id() ) )
  69              && ! is_paged()
  70              && $args['title'] === $defaults['title']
  71          ) {
  72              $contents = str_replace( ' rel=', ' aria-current="page" rel=', $contents );
  73          }
  74          $classname = $args['title_class'];
  75      }
  76  
  77      $wrap = $args['condition'] ? 'home_wrap' : 'single_wrap';
  78  
  79      $html = sprintf( $args[ $wrap ], $classname, $contents );
  80  
  81      /**
  82       * Filters the arguments for `twentytwenty_site_logo()`.
  83       *
  84       * @since Twenty Twenty 1.0
  85       *
  86       * @param string $html      Compiled HTML based on our arguments.
  87       * @param array  $args      Parsed arguments.
  88       * @param string $classname Class name based on current view, home or single.
  89       * @param string $contents  HTML for site title or logo.
  90       */
  91      $html = apply_filters( 'twentytwenty_site_logo', $html, $args, $classname, $contents );
  92  
  93      if ( ! $display ) {
  94          return $html;
  95      }
  96  
  97      echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
  98  }
  99  
 100  /**
 101   * Displays the site description.
 102   *
 103   * @since Twenty Twenty 1.0
 104   *
 105   * @param bool $display Display or return the HTML.
 106   * @return string The HTML to display.
 107   */
 108  function twentytwenty_site_description( $display = true ) {
 109      $description = get_bloginfo( 'description' );
 110  
 111      if ( ! $description ) {
 112          return;
 113      }
 114  
 115      $wrapper = '<div class="site-description">%s</div><!-- .site-description -->';
 116  
 117      $html = sprintf( $wrapper, esc_html( $description ) );
 118  
 119      /**
 120       * Filters the HTML for the site description.
 121       *
 122       * @since Twenty Twenty 1.0
 123       *
 124       * @param string $html        The HTML to display.
 125       * @param string $description Site description via `bloginfo()`.
 126       * @param string $wrapper     The format used in case you want to reuse it in a `sprintf()`.
 127       */
 128      $html = apply_filters( 'twentytwenty_site_description', $html, $description, $wrapper );
 129  
 130      if ( ! $display ) {
 131          return $html;
 132      }
 133  
 134      echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
 135  }
 136  
 137  /**
 138   * Comments
 139   */
 140  
 141  /**
 142   * Checks if the specified comment is written by the author of the post commented on.
 143   *
 144   * @since Twenty Twenty 1.0
 145   *
 146   * @param object $comment Comment data.
 147   * @return bool
 148   */
 149  function twentytwenty_is_comment_by_post_author( $comment = null ) {
 150  
 151      if ( is_object( $comment ) && $comment->user_id > 0 ) {
 152  
 153          $user = get_userdata( $comment->user_id );
 154          $post = get_post( $comment->comment_post_ID );
 155  
 156          if ( ! empty( $user ) && ! empty( $post ) ) {
 157  
 158              return $comment->user_id === $post->post_author;
 159  
 160          }
 161      }
 162      return false;
 163  }
 164  
 165  /**
 166   * Filters comment reply link to not JS scroll.
 167   *
 168   * Filter the comment reply link to add a class indicating it should not use JS slow-scroll, as it
 169   * makes it scroll to the wrong position on the page.
 170   *
 171   * @since Twenty Twenty 1.0
 172   *
 173   * @param string $link Link to the top of the page.
 174   * @return string Link to the top of the page.
 175   */
 176  function twentytwenty_filter_comment_reply_link( $link ) {
 177  
 178      $link = str_replace( 'class=\'', 'class=\'do-not-scroll ', $link );
 179      return $link;
 180  }
 181  
 182  add_filter( 'comment_reply_link', 'twentytwenty_filter_comment_reply_link' );
 183  
 184  /**
 185   * Post Meta
 186   */
 187  
 188  /**
 189   * Retrieves and displays the post meta.
 190   *
 191   * If it's a single post, outputs the post meta values specified in the Customizer settings.
 192   *
 193   * @since Twenty Twenty 1.0
 194   *
 195   * @param int    $post_id  The ID of the post for which the post meta should be output.
 196   * @param string $location Which post meta location to output – single or preview.
 197   */
 198  function twentytwenty_the_post_meta( $post_id = null, $location = 'single-top' ) {
 199  
 200      echo twentytwenty_get_post_meta( $post_id, $location ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in twentytwenty_get_post_meta().
 201  }
 202  
 203  /**
 204   * Filters the edit post link to add an icon and use the post meta structure.
 205   *
 206   * @since Twenty Twenty 1.0
 207   *
 208   * @param string $link    Anchor tag for the edit link.
 209   * @param int    $post_id Post ID.
 210   * @param string $text    Anchor text.
 211   */
 212  function twentytwenty_edit_post_link( $link, $post_id, $text ) {
 213      if ( is_admin() ) {
 214          return $link;
 215      }
 216  
 217      $edit_url = get_edit_post_link( $post_id );
 218  
 219      if ( ! $edit_url ) {
 220          return;
 221      }
 222  
 223      $text = sprintf(
 224          wp_kses(
 225              /* translators: %s: Post title. Only visible to screen readers. */
 226              __( 'Edit <span class="screen-reader-text">%s</span>', 'twentytwenty' ),
 227              array(
 228                  'span' => array(
 229                      'class' => array(),
 230                  ),
 231              )
 232          ),
 233          get_the_title( $post_id )
 234      );
 235  
 236      return '<div class="post-meta-wrapper post-meta-edit-link-wrapper"><ul class="post-meta"><li class="post-edit meta-wrapper"><span class="meta-icon">' . twentytwenty_get_theme_svg( 'edit' ) . '</span><span class="meta-text"><a href="' . esc_url( $edit_url ) . '">' . $text . '</a></span></li></ul><!-- .post-meta --></div><!-- .post-meta-wrapper -->';
 237  }
 238  
 239  add_filter( 'edit_post_link', 'twentytwenty_edit_post_link', 10, 3 );
 240  
 241  /**
 242   * Retrieves the post meta.
 243   *
 244   * @since Twenty Twenty 1.0
 245   *
 246   * @param int    $post_id  The ID of the post.
 247   * @param string $location The location where the meta is shown.
 248   */
 249  function twentytwenty_get_post_meta( $post_id = null, $location = 'single-top' ) {
 250  
 251      // Require post ID.
 252      if ( ! $post_id ) {
 253          return;
 254      }
 255  
 256      /**
 257       * Filters post types array.
 258       *
 259       * This filter can be used to hide post meta information of post, page or custom post type
 260       * registered by child themes or plugins.
 261       *
 262       * @since Twenty Twenty 1.0
 263       *
 264       * @param array Array of post types.
 265       */
 266      $disallowed_post_types = apply_filters( 'twentytwenty_disallowed_post_types_for_meta_output', array( 'page' ) );
 267  
 268      // Check whether the post type is allowed to output post meta.
 269      if ( in_array( get_post_type( $post_id ), $disallowed_post_types, true ) ) {
 270          return;
 271      }
 272  
 273      $post_meta_wrapper_classes = '';
 274      $post_meta_classes         = '';
 275  
 276      // Get the post meta settings for the location specified.
 277      if ( 'single-top' === $location ) {
 278          /**
 279           * Filters post meta info visibility.
 280           *
 281           * Use this filter to hide post meta information like Author, Post date, Comments, Is sticky status.
 282           *
 283           * @since Twenty Twenty 1.0
 284           *
 285           * @param array $args {
 286           *     @type string $author
 287           *     @type string $post-date
 288           *     @type string $comments
 289           *     @type string $sticky
 290           * }
 291           */
 292          $post_meta = apply_filters(
 293              'twentytwenty_post_meta_location_single_top',
 294              array(
 295                  'author',
 296                  'post-date',
 297                  'comments',
 298                  'sticky',
 299              )
 300          );
 301  
 302          $post_meta_wrapper_classes = ' post-meta-single post-meta-single-top';
 303  
 304      } elseif ( 'single-bottom' === $location ) {
 305  
 306          /**
 307           * Filters post tags visibility.
 308           *
 309           * Use this filter to hide post tags.
 310           *
 311           * @since Twenty Twenty 1.0
 312           *
 313           * @param array $args {
 314           *     @type string $tags
 315           * }
 316           */
 317          $post_meta = apply_filters(
 318              'twentytwenty_post_meta_location_single_bottom',
 319              array(
 320                  'tags',
 321              )
 322          );
 323  
 324          $post_meta_wrapper_classes = ' post-meta-single post-meta-single-bottom';
 325  
 326      }
 327  
 328      // If the post meta setting has the value 'empty', it's explicitly empty and the default post meta shouldn't be output.
 329      if ( $post_meta && ! in_array( 'empty', $post_meta, true ) ) {
 330  
 331          // Make sure we don't output an empty container.
 332          $has_meta = false;
 333  
 334          $the_post = get_post( $post_id );
 335          setup_postdata( $the_post );
 336  
 337          ob_start();
 338  
 339          ?>
 340  
 341          <div class="post-meta-wrapper<?php echo esc_attr( $post_meta_wrapper_classes ); ?>">
 342  
 343              <ul class="post-meta<?php echo esc_attr( $post_meta_classes ); ?>">
 344  
 345                  <?php
 346  
 347                  /**
 348                   * Fires before post meta HTML display.
 349                   *
 350                   * Allow output of additional post meta info to be added by child themes and plugins.
 351                   *
 352                   * @since Twenty Twenty 1.0
 353                   * @since Twenty Twenty 1.1 Added the `$post_meta` and `$location` parameters.
 354                   *
 355                   * @param int    $post_id   Post ID.
 356                   * @param array  $post_meta An array of post meta information.
 357                   * @param string $location  The location where the meta is shown.
 358                   *                          Accepts 'single-top' or 'single-bottom'.
 359                   */
 360                  do_action( 'twentytwenty_start_of_post_meta_list', $post_id, $post_meta, $location );
 361  
 362                  // Author.
 363                  if ( post_type_supports( get_post_type( $post_id ), 'author' ) && in_array( 'author', $post_meta, true ) ) {
 364  
 365                      $has_meta = true;
 366                      ?>
 367                      <li class="post-author meta-wrapper">
 368                          <span class="meta-icon">
 369                              <span class="screen-reader-text">
 370                                  <?php
 371                                  /* translators: Hidden accessibility text. */
 372                                  _e( 'Post author', 'twentytwenty' );
 373                                  ?>
 374                              </span>
 375                              <?php twentytwenty_the_theme_svg( 'user' ); ?>
 376                          </span>
 377                          <span class="meta-text">
 378                              <?php
 379                              printf(
 380                                  /* translators: %s: Author name. */
 381                                  __( 'By %s', 'twentytwenty' ),
 382                                  '<a href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . esc_html( get_the_author_meta( 'display_name' ) ) . '</a>'
 383                              );
 384                              ?>
 385                          </span>
 386                      </li>
 387                      <?php
 388  
 389                  }
 390  
 391                  // Post date.
 392                  if ( in_array( 'post-date', $post_meta, true ) ) {
 393  
 394                      $has_meta = true;
 395                      ?>
 396                      <li class="post-date meta-wrapper">
 397                          <span class="meta-icon">
 398                              <span class="screen-reader-text">
 399                                  <?php
 400                                  /* translators: Hidden accessibility text. */
 401                                  _e( 'Post date', 'twentytwenty' );
 402                                  ?>
 403                              </span>
 404                              <?php twentytwenty_the_theme_svg( 'calendar' ); ?>
 405                          </span>
 406                          <span class="meta-text">
 407                              <a href="<?php the_permalink(); ?>"><?php the_time( get_option( 'date_format' ) ); ?></a>
 408                          </span>
 409                      </li>
 410                      <?php
 411  
 412                  }
 413  
 414                  // Categories.
 415                  if ( in_array( 'categories', $post_meta, true ) && has_category() ) {
 416  
 417                      $has_meta = true;
 418                      ?>
 419                      <li class="post-categories meta-wrapper">
 420                          <span class="meta-icon">
 421                              <span class="screen-reader-text">
 422                                  <?php
 423                                  /* translators: Hidden accessibility text. */
 424                                  _e( 'Categories', 'twentytwenty' );
 425                                  ?>
 426                              </span>
 427                              <?php twentytwenty_the_theme_svg( 'folder' ); ?>
 428                          </span>
 429                          <span class="meta-text">
 430                              <?php _ex( 'In', 'A string that is output before one or more categories', 'twentytwenty' ); ?> <?php the_category( ', ' ); ?>
 431                          </span>
 432                      </li>
 433                      <?php
 434  
 435                  }
 436  
 437                  // Tags.
 438                  if ( in_array( 'tags', $post_meta, true ) && has_tag() ) {
 439  
 440                      $has_meta = true;
 441                      ?>
 442                      <li class="post-tags meta-wrapper">
 443                          <span class="meta-icon">
 444                              <span class="screen-reader-text">
 445                                  <?php
 446                                  /* translators: Hidden accessibility text. */
 447                                  _e( 'Tags', 'twentytwenty' );
 448                                  ?>
 449                              </span>
 450                              <?php twentytwenty_the_theme_svg( 'tag' ); ?>
 451                          </span>
 452                          <span class="meta-text">
 453                              <?php the_tags( '', ', ', '' ); ?>
 454                          </span>
 455                      </li>
 456                      <?php
 457  
 458                  }
 459  
 460                  // Comments link.
 461                  if ( in_array( 'comments', $post_meta, true ) && ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
 462  
 463                      $has_meta = true;
 464                      ?>
 465                      <li class="post-comment-link meta-wrapper">
 466                          <span class="meta-icon">
 467                              <?php twentytwenty_the_theme_svg( 'comment' ); ?>
 468                          </span>
 469                          <span class="meta-text">
 470                              <?php comments_popup_link(); ?>
 471                          </span>
 472                      </li>
 473                      <?php
 474  
 475                  }
 476  
 477                  // Sticky.
 478                  if ( in_array( 'sticky', $post_meta, true ) && is_sticky() ) {
 479  
 480                      $has_meta = true;
 481                      ?>
 482                      <li class="post-sticky meta-wrapper">
 483                          <span class="meta-icon">
 484                              <?php twentytwenty_the_theme_svg( 'bookmark' ); ?>
 485                          </span>
 486                          <span class="meta-text">
 487                              <?php _e( 'Sticky post', 'twentytwenty' ); ?>
 488                          </span>
 489                      </li>
 490                      <?php
 491  
 492                  }
 493  
 494                  /**
 495                   * Fires after post meta HTML display.
 496                   *
 497                   * Allow output of additional post meta info to be added by child themes and plugins.
 498                   *
 499                   * @since Twenty Twenty 1.0
 500                   * @since Twenty Twenty 1.1 Added the `$post_meta` and `$location` parameters.
 501                   *
 502                   * @param int    $post_id   Post ID.
 503                   * @param array  $post_meta An array of post meta information.
 504                   * @param string $location  The location where the meta is shown.
 505                   *                          Accepts 'single-top' or 'single-bottom'.
 506                   */
 507                  do_action( 'twentytwenty_end_of_post_meta_list', $post_id, $post_meta, $location );
 508  
 509                  ?>
 510  
 511              </ul><!-- .post-meta -->
 512  
 513          </div><!-- .post-meta-wrapper -->
 514  
 515          <?php
 516  
 517          wp_reset_postdata();
 518  
 519          $meta_output = ob_get_clean();
 520  
 521          // If there is meta to output, return it.
 522          if ( $has_meta && $meta_output ) {
 523  
 524              return $meta_output;
 525  
 526          }
 527      }
 528  }
 529  
 530  /**
 531   * Menus
 532   */
 533  
 534  /**
 535   * Filters classes of wp_list_pages items to match menu items.
 536   *
 537   * Filter the class applied to wp_list_pages() items with children to match the menu class, to simplify.
 538   * styling of sub levels in the fallback. Only applied if the match_menu_classes argument is set.
 539   *
 540   * @since Twenty Twenty 1.0
 541   *
 542   * @param string[] $css_class    An array of CSS classes to be applied to each list item.
 543   * @param WP_Post  $page         Page data object.
 544   * @param int      $depth        Depth of page, used for padding.
 545   * @param array    $args         An array of arguments.
 546   * @return array CSS class names.
 547   */
 548  function twentytwenty_filter_wp_list_pages_item_classes( $css_class, $page, $depth, $args ) {
 549  
 550      // Only apply to wp_list_pages() calls with match_menu_classes set to true.
 551      $match_menu_classes = isset( $args['match_menu_classes'] );
 552  
 553      if ( ! $match_menu_classes ) {
 554          return $css_class;
 555      }
 556  
 557      // Add current menu item class.
 558      if ( in_array( 'current_page_item', $css_class, true ) ) {
 559          $css_class[] = 'current-menu-item';
 560      }
 561  
 562      // Add menu item has children class.
 563      if ( in_array( 'page_item_has_children', $css_class, true ) ) {
 564          $css_class[] = 'menu-item-has-children';
 565      }
 566  
 567      return $css_class;
 568  }
 569  
 570  add_filter( 'page_css_class', 'twentytwenty_filter_wp_list_pages_item_classes', 10, 4 );
 571  
 572  /**
 573   * Adds a Sub Nav Toggle to the Expanded Menu and Mobile Menu.
 574   *
 575   * @since Twenty Twenty 1.0
 576   *
 577   * @param stdClass $args  An object of wp_nav_menu() arguments.
 578   * @param WP_Post  $item  Menu item data object.
 579   * @return stdClass An object of wp_nav_menu() arguments.
 580   */
 581  function twentytwenty_add_sub_toggles_to_main_menu( $args, $item ) {
 582  
 583      // Add sub menu toggles to the Expanded Menu with toggles.
 584      if ( isset( $args->show_toggles ) && $args->show_toggles ) {
 585  
 586          // Wrap the menu item link contents in a div, used for positioning.
 587          $args->before = '<div class="ancestor-wrapper">';
 588          $args->after  = '';
 589  
 590          // Add a toggle to items with children.
 591          if ( in_array( 'menu-item-has-children', $item->classes, true ) ) {
 592  
 593              $toggle_target_string = '.menu-modal .menu-item-' . $item->ID . ' > .sub-menu';
 594              $toggle_duration      = twentytwenty_toggle_duration();
 595  
 596              // Add the sub menu toggle.
 597              $args->after .= '<button class="toggle sub-menu-toggle fill-children-current-color" data-toggle-target="' . $toggle_target_string . '" data-toggle-type="slidetoggle" data-toggle-duration="' . absint( $toggle_duration ) . '" aria-expanded="false"><span class="screen-reader-text">' .
 598                  /* translators: Hidden accessibility text. */
 599                  __( 'Show sub menu', 'twentytwenty' ) .
 600              '</span>' . twentytwenty_get_theme_svg( 'chevron-down' ) . '</button>';
 601  
 602          }
 603  
 604          // Close the wrapper.
 605          $args->after .= '</div><!-- .ancestor-wrapper -->';
 606  
 607          // Add sub menu icons to the primary menu without toggles.
 608      } elseif ( 'primary' === $args->theme_location ) {
 609          if ( in_array( 'menu-item-has-children', $item->classes, true ) ) {
 610              $args->after = '<span class="icon"></span>';
 611          } else {
 612              $args->after = '';
 613          }
 614      }
 615  
 616      return $args;
 617  }
 618  
 619  add_filter( 'nav_menu_item_args', 'twentytwenty_add_sub_toggles_to_main_menu', 10, 2 );
 620  
 621  /**
 622   * Displays SVG icons in social links menu.
 623   *
 624   * @since Twenty Twenty 1.0
 625   *
 626   * @param string   $item_output The menu item's starting HTML output.
 627   * @param WP_Post  $item        Menu item data object.
 628   * @param int      $depth       Depth of the menu. Used for padding.
 629   * @param stdClass $args        An object of wp_nav_menu() arguments.
 630   * @return string The menu item output with social icon.
 631   */
 632  function twentytwenty_nav_menu_social_icons( $item_output, $item, $depth, $args ) {
 633      // Change SVG icon inside social links menu if there is supported URL.
 634      if ( 'social' === $args->theme_location ) {
 635          $svg = TwentyTwenty_SVG_Icons::get_social_link_svg( $item->url );
 636          if ( empty( $svg ) ) {
 637              $svg = twentytwenty_get_theme_svg( 'link' );
 638          }
 639          $item_output = str_replace( $args->link_after, '</span>' . $svg, $item_output );
 640      }
 641  
 642      return $item_output;
 643  }
 644  
 645  add_filter( 'walker_nav_menu_start_el', 'twentytwenty_nav_menu_social_icons', 10, 4 );
 646  
 647  /**
 648   * Classes
 649   */
 650  
 651  /**
 652   * Adds 'no-js' class.
 653   *
 654   * If we're missing JavaScript support, the HTML element will have a 'no-js' class.
 655   *
 656   * @since Twenty Twenty 1.0
 657   */
 658  function twentytwenty_no_js_class() {
 659  
 660      ?>
 661      <script>document.documentElement.className = document.documentElement.className.replace( 'no-js', 'js' );</script>
 662      <?php
 663  }
 664  
 665  add_action( 'wp_head', 'twentytwenty_no_js_class' );
 666  
 667  /**
 668   * Adds conditional body classes.
 669   *
 670   * @since Twenty Twenty 1.0
 671   *
 672   * @global WP_Post $post Global post object.
 673   *
 674   * @param array $classes Classes added to the body tag.
 675   * @return array Classes added to the body tag.
 676   */
 677  function twentytwenty_body_classes( $classes ) {
 678  
 679      global $post;
 680      $post_type = isset( $post ) ? $post->post_type : false;
 681  
 682      // Check whether we're singular.
 683      if ( is_singular() ) {
 684          $classes[] = 'singular';
 685      }
 686  
 687      // Check whether the current page should have an overlay header.
 688      if ( is_page_template( array( 'templates/template-cover.php' ) ) ) {
 689          $classes[] = 'overlay-header';
 690      }
 691  
 692      // Check whether the current page has full-width content.
 693      if ( is_page_template( array( 'templates/template-full-width.php' ) ) ) {
 694          $classes[] = 'has-full-width-content';
 695      }
 696  
 697      // Check for enabled search.
 698      if ( true === get_theme_mod( 'enable_header_search', true ) ) {
 699          $classes[] = 'enable-search-modal';
 700      }
 701  
 702      // Check for post thumbnail.
 703      if ( is_singular() && has_post_thumbnail() ) {
 704          $classes[] = 'has-post-thumbnail';
 705      } elseif ( is_singular() ) {
 706          $classes[] = 'missing-post-thumbnail';
 707      }
 708  
 709      // Check whether we're in the customizer preview.
 710      if ( is_customize_preview() ) {
 711          $classes[] = 'customizer-preview';
 712      }
 713  
 714      // Check if posts have single pagination.
 715      if ( is_single() && ( get_next_post() || get_previous_post() ) ) {
 716          $classes[] = 'has-single-pagination';
 717      } else {
 718          $classes[] = 'has-no-pagination';
 719      }
 720  
 721      // Check if we're showing comments.
 722      if ( $post && ( ( 'post' === $post_type || comments_open() || get_comments_number() ) && ! post_password_required() ) ) {
 723          $classes[] = 'showing-comments';
 724      } else {
 725          $classes[] = 'not-showing-comments';
 726      }
 727  
 728      // Check if avatars are visible.
 729      $classes[] = get_option( 'show_avatars' ) ? 'show-avatars' : 'hide-avatars';
 730  
 731      // Slim page template class names (class = name - file suffix).
 732      if ( is_page_template() ) {
 733          $classes[] = basename( get_page_template_slug(), '.php' );
 734      }
 735  
 736      // Check for the elements output in the top part of the footer.
 737      $has_footer_menu = has_nav_menu( 'footer' );
 738      $has_social_menu = has_nav_menu( 'social' );
 739      $has_sidebar_1   = is_active_sidebar( 'sidebar-1' );
 740      $has_sidebar_2   = is_active_sidebar( 'sidebar-2' );
 741  
 742      // Add a class indicating whether those elements are output.
 743      if ( $has_footer_menu || $has_social_menu || $has_sidebar_1 || $has_sidebar_2 ) {
 744          $classes[] = 'footer-top-visible';
 745      } else {
 746          $classes[] = 'footer-top-hidden';
 747      }
 748  
 749      // Get header/footer background color.
 750      $header_footer_background = get_theme_mod( 'header_footer_background_color', '#ffffff' );
 751      $header_footer_background = strtolower( '#' . ltrim( $header_footer_background, '#' ) );
 752  
 753      // Get content background color.
 754      $background_color = get_theme_mod( 'background_color', 'f5efe0' );
 755      $background_color = strtolower( '#' . ltrim( $background_color, '#' ) );
 756  
 757      // Add extra class if main background and header/footer background are the same color.
 758      if ( $background_color === $header_footer_background ) {
 759          $classes[] = 'reduced-spacing';
 760      }
 761  
 762      return $classes;
 763  }
 764  
 765  add_filter( 'body_class', 'twentytwenty_body_classes' );
 766  
 767  /**
 768   * Archives
 769   */
 770  
 771  /**
 772   * Filters the archive title and styles the word before the first colon.
 773   *
 774   * @since Twenty Twenty 1.0
 775   *
 776   * @param string $title Current archive title.
 777   * @return string Current archive title.
 778   */
 779  function twentytwenty_get_the_archive_title( $title ) {
 780  
 781      /**
 782       * Filters the regular expression used to style the word before the first colon.
 783       *
 784       * @since Twenty Twenty 1.0
 785       *
 786       * @param array $regex An array of regular expression pattern and replacement.
 787       */
 788      $regex = apply_filters(
 789          'twentytwenty_get_the_archive_title_regex',
 790          array(
 791              'pattern'     => '/(\A[^\:]+\:)/',
 792              'replacement' => '<span class="color-accent">$1</span>',
 793          )
 794      );
 795  
 796      if ( empty( $regex ) ) {
 797  
 798          return $title;
 799  
 800      }
 801  
 802      return preg_replace( $regex['pattern'], $regex['replacement'], $title );
 803  }
 804  
 805  add_filter( 'get_the_archive_title', 'twentytwenty_get_the_archive_title' );
 806  
 807  /**
 808   * Miscellaneous
 809   */
 810  
 811  /**
 812   * Toggles animation duration in milliseconds.
 813   *
 814   * @since Twenty Twenty 1.0
 815   *
 816   * @return int Duration in milliseconds
 817   */
 818  function twentytwenty_toggle_duration() {
 819      /**
 820       * Filters the animation duration/speed used usually for submenu toggles.
 821       *
 822       * @since Twenty Twenty 1.0
 823       *
 824       * @param int $duration Duration in milliseconds.
 825       */
 826      $duration = apply_filters( 'twentytwenty_toggle_duration', 250 );
 827  
 828      return $duration;
 829  }
 830  
 831  /**
 832   * Gets unique ID.
 833   *
 834   * This is a PHP implementation of Underscore's uniqueId method. A static variable
 835   * contains an integer that is incremented with each call. This number is returned
 836   * with the optional prefix. As such the returned value is not universally unique,
 837   * but it is unique across the life of the PHP process.
 838   *
 839   * @since Twenty Twenty 1.0
 840   *
 841   * @see wp_unique_id() Themes requiring WordPress 5.0.3 and greater should use this instead.
 842   *
 843   * @param string $prefix Prefix for the returned ID.
 844   * @return string Unique ID.
 845   */
 846  function twentytwenty_unique_id( $prefix = '' ) {
 847      static $id_counter = 0;
 848      if ( function_exists( 'wp_unique_id' ) ) {
 849          return wp_unique_id( $prefix );
 850      }
 851      return $prefix . (string) ++$id_counter;
 852  }


Generated : Tue Jul 15 08:20:01 2025 Cross-referenced by PHPXref