[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/blocks/ -> search.php (source)

   1  <?php
   2  /**
   3   * Server-side rendering of the `core/search` block.
   4   *
   5   * @package WordPress
   6   */
   7  
   8  /**
   9   * Dynamically renders the `core/search` block.
  10   *
  11   * @param array $attributes The block attributes.
  12   *
  13   * @return string The search block markup.
  14   */
  15  function render_block_core_search( $attributes ) {
  16      static $instance_id = 0;
  17  
  18      // Older versions of the Search block defaulted the label and buttonText
  19      // attributes to `__( 'Search' )` meaning that many posts contain `<!--
  20      // wp:search /-->`. Support these by defaulting an undefined label and
  21      // buttonText to `__( 'Search' )`.
  22      $attributes = wp_parse_args(
  23          $attributes,
  24          array(
  25              'label'      => __( 'Search' ),
  26              'buttonText' => __( 'Search' ),
  27          )
  28      );
  29  
  30      $input_id         = 'wp-block-search__input-' . ++$instance_id;
  31      $classnames       = classnames_for_block_core_search( $attributes );
  32      $show_label       = ( ! empty( $attributes['showLabel'] ) ) ? true : false;
  33      $use_icon_button  = ( ! empty( $attributes['buttonUseIcon'] ) ) ? true : false;
  34      $show_input       = ( ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'] ) ? false : true;
  35      $show_button      = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true;
  36      $input_markup     = '';
  37      $button_markup    = '';
  38      $inline_styles    = styles_for_block_core_search( $attributes );
  39      $color_classes    = get_color_classes_for_block_core_search( $attributes );
  40      $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
  41          'button-inside' === $attributes['buttonPosition'];
  42      // Border color classes need to be applied to the elements that have a border color.
  43      $border_color_classes = get_border_color_classes_for_block_core_search( $attributes );
  44  
  45      $label_inner_html = empty( $attributes['label'] ) ? __( 'Search' ) : wp_kses_post( $attributes['label'] );
  46  
  47      $label_markup = sprintf(
  48          '<label for="%1$s" class="wp-block-search__label screen-reader-text">%2$s</label>',
  49          esc_attr( $input_id ),
  50          $label_inner_html
  51      );
  52      if ( $show_label && ! empty( $attributes['label'] ) ) {
  53          $label_markup = sprintf(
  54              '<label for="%1$s" class="wp-block-search__label">%2$s</label>',
  55              $input_id,
  56              $label_inner_html
  57          );
  58      }
  59  
  60      if ( $show_input ) {
  61          $input_classes = ! $is_button_inside ? $border_color_classes : '';
  62          $input_markup  = sprintf(
  63              '<input type="search" id="%s" class="wp-block-search__input %s" name="s" value="%s" placeholder="%s" %s required />',
  64              $input_id,
  65              esc_attr( $input_classes ),
  66              esc_attr( get_search_query() ),
  67              esc_attr( $attributes['placeholder'] ),
  68              $inline_styles['input']
  69          );
  70      }
  71  
  72      if ( $show_button ) {
  73          $button_internal_markup = '';
  74          $button_classes         = $color_classes;
  75          $aria_label             = '';
  76  
  77          if ( ! $is_button_inside ) {
  78              $button_classes .= ' ' . $border_color_classes;
  79          }
  80          if ( ! $use_icon_button ) {
  81              if ( ! empty( $attributes['buttonText'] ) ) {
  82                  $button_internal_markup = wp_kses_post( $attributes['buttonText'] );
  83              }
  84          } else {
  85              $aria_label      = sprintf( 'aria-label="%s"', esc_attr( wp_strip_all_tags( $attributes['buttonText'] ) ) );
  86              $button_classes .= ' has-icon';
  87  
  88              $button_internal_markup =
  89                  '<svg id="search-icon" class="search-icon" viewBox="0 0 24 24" width="24" height="24">
  90                      <path d="M13.5 6C10.5 6 8 8.5 8 11.5c0 1.1.3 2.1.9 3l-3.4 3 1 1.1 3.4-2.9c1 .9 2.2 1.4 3.6 1.4 3 0 5.5-2.5 5.5-5.5C19 8.5 16.5 6 13.5 6zm0 9.5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"></path>
  91                  </svg>';
  92          }
  93  
  94          $button_markup = sprintf(
  95              '<button type="submit" class="wp-block-search__button %s" %s %s>%s</button>',
  96              esc_attr( $button_classes ),
  97              $inline_styles['button'],
  98              $aria_label,
  99              $button_internal_markup
 100          );
 101      }
 102  
 103      $field_markup_classes = $is_button_inside ? $border_color_classes : '';
 104      $field_markup         = sprintf(
 105          '<div class="wp-block-search__inside-wrapper %s" %s>%s</div>',
 106          esc_attr( $field_markup_classes ),
 107          $inline_styles['wrapper'],
 108          $input_markup . $button_markup
 109      );
 110      $wrapper_attributes   = get_block_wrapper_attributes( array( 'class' => $classnames ) );
 111  
 112      return sprintf(
 113          '<form role="search" method="get" action="%s" %s>%s</form>',
 114          esc_url( home_url( '/' ) ),
 115          $wrapper_attributes,
 116          $label_markup . $field_markup
 117      );
 118  }
 119  
 120  /**
 121   * Registers the `core/search` block on the server.
 122   */
 123  function register_block_core_search() {
 124      register_block_type_from_metadata(
 125          __DIR__ . '/search',
 126          array(
 127              'render_callback' => 'render_block_core_search',
 128          )
 129      );
 130  }
 131  add_action( 'init', 'register_block_core_search' );
 132  
 133  /**
 134   * Builds the correct top level classnames for the 'core/search' block.
 135   *
 136   * @param array $attributes The block attributes.
 137   *
 138   * @return string The classnames used in the block.
 139   */
 140  function classnames_for_block_core_search( $attributes ) {
 141      $classnames = array();
 142  
 143      if ( ! empty( $attributes['buttonPosition'] ) ) {
 144          if ( 'button-inside' === $attributes['buttonPosition'] ) {
 145              $classnames[] = 'wp-block-search__button-inside';
 146          }
 147  
 148          if ( 'button-outside' === $attributes['buttonPosition'] ) {
 149              $classnames[] = 'wp-block-search__button-outside';
 150          }
 151  
 152          if ( 'no-button' === $attributes['buttonPosition'] ) {
 153              $classnames[] = 'wp-block-search__no-button';
 154          }
 155  
 156          if ( 'button-only' === $attributes['buttonPosition'] ) {
 157              $classnames[] = 'wp-block-search__button-only';
 158          }
 159      }
 160  
 161      if ( isset( $attributes['buttonUseIcon'] ) ) {
 162          if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
 163              if ( $attributes['buttonUseIcon'] ) {
 164                  $classnames[] = 'wp-block-search__icon-button';
 165              } else {
 166                  $classnames[] = 'wp-block-search__text-button';
 167              }
 168          }
 169      }
 170  
 171      return implode( ' ', $classnames );
 172  }
 173  
 174  /**
 175   * Builds an array of inline styles for the search block.
 176   *
 177   * The result will contain one entry for shared styles such as those for the
 178   * inner input or button and a second for the inner wrapper should the block
 179   * be positioning the button "inside".
 180   *
 181   * @param  array $attributes The block attributes.
 182   *
 183   * @return array Style HTML attribute.
 184   */
 185  function styles_for_block_core_search( $attributes ) {
 186      $wrapper_styles   = array();
 187      $button_styles    = array();
 188      $input_styles     = array();
 189      $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
 190          'button-inside' === $attributes['buttonPosition'];
 191  
 192      // Add width styles.
 193      $has_width   = ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] );
 194      $button_only = ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'];
 195  
 196      if ( $has_width && ! $button_only ) {
 197          $wrapper_styles[] = sprintf(
 198              'width: %d%s;',
 199              esc_attr( $attributes['width'] ),
 200              esc_attr( $attributes['widthUnit'] )
 201          );
 202      }
 203  
 204      // Add border width styles.
 205      $has_border_width = ! empty( $attributes['style']['border']['width'] );
 206  
 207      if ( $has_border_width ) {
 208          $border_width = $attributes['style']['border']['width'];
 209  
 210          if ( $is_button_inside ) {
 211              $wrapper_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
 212          } else {
 213              $button_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
 214              $input_styles[]  = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
 215          }
 216      }
 217  
 218      // Add border radius styles.
 219      $has_border_radius = ! empty( $attributes['style']['border']['radius'] );
 220  
 221      if ( $has_border_radius ) {
 222          $default_padding = '4px';
 223          $border_radius   = $attributes['style']['border']['radius'];
 224  
 225          if ( is_array( $border_radius ) ) {
 226              // Apply styles for individual corner border radii.
 227              foreach ( $border_radius as $key => $value ) {
 228                  if ( null !== $value ) {
 229                      // Convert camelCase key to kebab-case.
 230                      $name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
 231  
 232                      // Add shared styles for individual border radii for input & button.
 233                      $border_style    = sprintf(
 234                          'border-%s-radius: %s;',
 235                          esc_attr( $name ),
 236                          esc_attr( $value )
 237                      );
 238                      $input_styles[]  = $border_style;
 239                      $button_styles[] = $border_style;
 240  
 241                      // Add adjusted border radius styles for the wrapper element
 242                      // if button is positioned inside.
 243                      if ( $is_button_inside && intval( $value ) !== 0 ) {
 244                          $wrapper_styles[] = sprintf(
 245                              'border-%s-radius: calc(%s + %s);',
 246                              esc_attr( $name ),
 247                              esc_attr( $value ),
 248                              $default_padding
 249                          );
 250                      }
 251                  }
 252              }
 253          } else {
 254              // Numeric check is for backwards compatibility purposes.
 255              $border_radius   = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
 256              $border_style    = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
 257              $input_styles[]  = $border_style;
 258              $button_styles[] = $border_style;
 259  
 260              if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
 261                  // Adjust wrapper border radii to maintain visual consistency
 262                  // with inner elements when button is positioned inside.
 263                  $wrapper_styles[] = sprintf(
 264                      'border-radius: calc(%s + %s);',
 265                      esc_attr( $border_radius ),
 266                      $default_padding
 267                  );
 268              }
 269          }
 270      }
 271  
 272      // Add border color styles.
 273      $has_border_color = ! empty( $attributes['style']['border']['color'] );
 274  
 275      if ( $has_border_color ) {
 276          $border_color = $attributes['style']['border']['color'];
 277  
 278          // Apply wrapper border color if button placed inside.
 279          if ( $is_button_inside ) {
 280              $wrapper_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
 281          } else {
 282              $button_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
 283              $input_styles[]  = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
 284          }
 285      }
 286  
 287      // Add color styles.
 288      $has_text_color = ! empty( $attributes['style']['color']['text'] );
 289      if ( $has_text_color ) {
 290          $button_styles[] = sprintf( 'color: %s;', esc_attr( $attributes['style']['color']['text'] ) );
 291      }
 292  
 293      $has_background_color = ! empty( $attributes['style']['color']['background'] );
 294      if ( $has_background_color ) {
 295          $button_styles[] = sprintf( 'background-color: %s;', esc_attr( $attributes['style']['color']['background'] ) );
 296      }
 297  
 298      $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
 299      if ( $has_custom_gradient ) {
 300          $button_styles[] = sprintf( 'background: %s;', $attributes['style']['color']['gradient'] );
 301      }
 302  
 303      return array(
 304          'input'   => ! empty( $input_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $input_styles ) ) ) : '',
 305          'button'  => ! empty( $button_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $button_styles ) ) ) : '',
 306          'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $wrapper_styles ) ) ) : '',
 307      );
 308  }
 309  
 310  /**
 311   * Returns border color classnames depending on whether there are named or custom border colors.
 312   *
 313   * @param array $attributes The block attributes.
 314   *
 315   * @return string The border color classnames to be applied to the block elements.
 316   */
 317  function get_border_color_classes_for_block_core_search( $attributes ) {
 318      $has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
 319      $border_color_classes    = ! empty( $attributes['borderColor'] ) ? sprintf( 'has-border-color has-%s-border-color', $attributes['borderColor'] ) : '';
 320      // If there's a border color style and no `borderColor` text string, we still want to add the generic `has-border-color` class name to the element.
 321      if ( $has_custom_border_color && empty( $attributes['borderColor'] ) ) {
 322          $border_color_classes = 'has-border-color';
 323      }
 324      return $border_color_classes;
 325  }
 326  
 327  /**
 328   * Returns color classnames depending on whether there are named or custom text and background colors.
 329   *
 330   * @param array $attributes The block attributes.
 331   *
 332   * @return string The color classnames to be applied to the block elements.
 333   */
 334  function get_color_classes_for_block_core_search( $attributes ) {
 335      $classnames = array();
 336  
 337      // Text color.
 338      $has_named_text_color  = ! empty( $attributes['textColor'] );
 339      $has_custom_text_color = ! empty( $attributes['style']['color']['text'] );
 340      if ( $has_named_text_color ) {
 341          $classnames[] = sprintf( 'has-text-color has-%s-color', $attributes['textColor'] );
 342      } elseif ( $has_custom_text_color ) {
 343          // If a custom 'textColor' was selected instead of a preset, still add the generic `has-text-color` class.
 344          $classnames[] = 'has-text-color';
 345      }
 346  
 347      // Background color.
 348      $has_named_background_color  = ! empty( $attributes['backgroundColor'] );
 349      $has_custom_background_color = ! empty( $attributes['style']['color']['background'] );
 350      $has_named_gradient          = ! empty( $attributes['gradient'] );
 351      $has_custom_gradient         = ! empty( $attributes['style']['color']['gradient'] );
 352      if (
 353          $has_named_background_color ||
 354          $has_custom_background_color ||
 355          $has_named_gradient ||
 356          $has_custom_gradient
 357      ) {
 358          $classnames[] = 'has-background';
 359      }
 360      if ( $has_named_background_color ) {
 361          $classnames[] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
 362      }
 363      if ( $has_named_gradient ) {
 364          $classnames[] = sprintf( 'has-%s-gradient-background', $attributes['gradient'] );
 365      }
 366  
 367      return implode( ' ', $classnames );
 368  }


Generated: Tue Dec 24 01:00:02 2024 Cross-referenced by PHPXref 0.7.1