[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/block-supports/ -> layout.php (source)

   1  <?php
   2  /**
   3   * Layout block support flag.
   4   *
   5   * @package WordPress
   6   * @since 5.8.0
   7   */
   8  
   9  /**
  10   * Registers the layout block attribute for block types that support it.
  11   *
  12   * @since 5.8.0
  13   * @access private
  14   *
  15   * @param WP_Block_Type $block_type Block Type.
  16   */
  17  function wp_register_layout_support( $block_type ) {
  18      $support_layout = block_has_support( $block_type, array( '__experimentalLayout' ), false );
  19      if ( $support_layout ) {
  20          if ( ! $block_type->attributes ) {
  21              $block_type->attributes = array();
  22          }
  23  
  24          if ( ! array_key_exists( 'layout', $block_type->attributes ) ) {
  25              $block_type->attributes['layout'] = array(
  26                  'type' => 'object',
  27              );
  28          }
  29      }
  30  }
  31  
  32  /**
  33   * Generates the CSS corresponding to the provided layout.
  34   *
  35   * @since 5.9.0
  36   * @since 6.1.0 Added `$block_spacing` param, use style engine to enqueue styles.
  37   * @access private
  38   *
  39   * @param string               $selector                      CSS selector.
  40   * @param array                $layout                        Layout object. The one that is passed has already checked
  41   *                                                            the existence of default block layout.
  42   * @param bool                 $has_block_gap_support         Optional. Whether the theme has support for the block gap. Default false.
  43   * @param string|string[]|null $gap_value                     Optional. The block gap value to apply. Default null.
  44   * @param bool                 $should_skip_gap_serialization Optional. Whether to skip applying the user-defined value set in the editor. Default false.
  45   * @param string               $fallback_gap_value            Optional. The block gap value to apply. Default '0.5em'.
  46   * @param array|null           $block_spacing                 Optional. Custom spacing set on the block. Default null.
  47   * @return string CSS styles on success. Else, empty string.
  48   */
  49  function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) {
  50      $layout_type   = isset( $layout['type'] ) ? $layout['type'] : 'default';
  51      $layout_styles = array();
  52  
  53      if ( 'default' === $layout_type ) {
  54          if ( $has_block_gap_support ) {
  55              if ( is_array( $gap_value ) ) {
  56                  $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null;
  57              }
  58              if ( null !== $gap_value && ! $should_skip_gap_serialization ) {
  59                  // Get spacing CSS variable from preset value if provided.
  60                  if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) {
  61                      $index_to_splice = strrpos( $gap_value, '|' ) + 1;
  62                      $slug            = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) );
  63                      $gap_value       = "var(--wp--preset--spacing--$slug)";
  64                  }
  65  
  66                  array_push(
  67                      $layout_styles,
  68                      array(
  69                          'selector'     => "$selector > *",
  70                          'declarations' => array(
  71                              'margin-block-start' => '0',
  72                              'margin-block-end'   => '0',
  73                          ),
  74                      ),
  75                      array(
  76                          'selector'     => "$selector$selector > * + *",
  77                          'declarations' => array(
  78                              'margin-block-start' => $gap_value,
  79                              'margin-block-end'   => '0',
  80                          ),
  81                      )
  82                  );
  83              }
  84          }
  85      } elseif ( 'constrained' === $layout_type ) {
  86          $content_size    = isset( $layout['contentSize'] ) ? $layout['contentSize'] : '';
  87          $wide_size       = isset( $layout['wideSize'] ) ? $layout['wideSize'] : '';
  88          $justify_content = isset( $layout['justifyContent'] ) ? $layout['justifyContent'] : 'center';
  89  
  90          $all_max_width_value  = $content_size ? $content_size : $wide_size;
  91          $wide_max_width_value = $wide_size ? $wide_size : $content_size;
  92  
  93          // Make sure there is a single CSS rule, and all tags are stripped for security.
  94          $all_max_width_value  = safecss_filter_attr( explode( ';', $all_max_width_value )[0] );
  95          $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] );
  96  
  97          $margin_left  = 'left' === $justify_content ? '0 !important' : 'auto !important';
  98          $margin_right = 'right' === $justify_content ? '0 !important' : 'auto !important';
  99  
 100          if ( $content_size || $wide_size ) {
 101              array_push(
 102                  $layout_styles,
 103                  array(
 104                      'selector'     => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))",
 105                      'declarations' => array(
 106                          'max-width'    => $all_max_width_value,
 107                          'margin-left'  => $margin_left,
 108                          'margin-right' => $margin_right,
 109                      ),
 110                  ),
 111                  array(
 112                      'selector'     => "$selector > .alignwide",
 113                      'declarations' => array( 'max-width' => $wide_max_width_value ),
 114                  ),
 115                  array(
 116                      'selector'     => "$selector .alignfull",
 117                      'declarations' => array( 'max-width' => 'none' ),
 118                  )
 119              );
 120  
 121              if ( isset( $block_spacing ) ) {
 122                  $block_spacing_values = wp_style_engine_get_styles(
 123                      array(
 124                          'spacing' => $block_spacing,
 125                      )
 126                  );
 127  
 128                  /*
 129                   * Handle negative margins for alignfull children of blocks with custom padding set.
 130                   * They're added separately because padding might only be set on one side.
 131                   */
 132                  if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) {
 133                      $padding_right   = $block_spacing_values['declarations']['padding-right'];
 134                      $layout_styles[] = array(
 135                          'selector'     => "$selector > .alignfull",
 136                          'declarations' => array( 'margin-right' => "calc($padding_right * -1)" ),
 137                      );
 138                  }
 139                  if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) {
 140                      $padding_left    = $block_spacing_values['declarations']['padding-left'];
 141                      $layout_styles[] = array(
 142                          'selector'     => "$selector > .alignfull",
 143                          'declarations' => array( 'margin-left' => "calc($padding_left * -1)" ),
 144                      );
 145                  }
 146              }
 147          }
 148  
 149          if ( 'left' === $justify_content ) {
 150              $layout_styles[] = array(
 151                  'selector'     => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))",
 152                  'declarations' => array( 'margin-left' => '0 !important' ),
 153              );
 154          }
 155  
 156          if ( 'right' === $justify_content ) {
 157              $layout_styles[] = array(
 158                  'selector'     => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))",
 159                  'declarations' => array( 'margin-right' => '0 !important' ),
 160              );
 161          }
 162  
 163          if ( $has_block_gap_support ) {
 164              if ( is_array( $gap_value ) ) {
 165                  $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null;
 166              }
 167              if ( null !== $gap_value && ! $should_skip_gap_serialization ) {
 168                  // Get spacing CSS variable from preset value if provided.
 169                  if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) {
 170                      $index_to_splice = strrpos( $gap_value, '|' ) + 1;
 171                      $slug            = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) );
 172                      $gap_value       = "var(--wp--preset--spacing--$slug)";
 173                  }
 174  
 175                  array_push(
 176                      $layout_styles,
 177                      array(
 178                          'selector'     => "$selector > *",
 179                          'declarations' => array(
 180                              'margin-block-start' => '0',
 181                              'margin-block-end'   => '0',
 182                          ),
 183                      ),
 184                      array(
 185                          'selector'     => "$selector$selector > * + *",
 186                          'declarations' => array(
 187                              'margin-block-start' => $gap_value,
 188                              'margin-block-end'   => '0',
 189                          ),
 190                      )
 191                  );
 192              }
 193          }
 194      } elseif ( 'flex' === $layout_type ) {
 195          $layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal';
 196  
 197          $justify_content_options = array(
 198              'left'   => 'flex-start',
 199              'right'  => 'flex-end',
 200              'center' => 'center',
 201          );
 202  
 203          $vertical_alignment_options = array(
 204              'top'    => 'flex-start',
 205              'center' => 'center',
 206              'bottom' => 'flex-end',
 207          );
 208  
 209          if ( 'horizontal' === $layout_orientation ) {
 210              $justify_content_options    += array( 'space-between' => 'space-between' );
 211              $vertical_alignment_options += array( 'stretch' => 'stretch' );
 212          } else {
 213              $justify_content_options    += array( 'stretch' => 'stretch' );
 214              $vertical_alignment_options += array( 'space-between' => 'space-between' );
 215          }
 216  
 217          if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) {
 218              $layout_styles[] = array(
 219                  'selector'     => $selector,
 220                  'declarations' => array( 'flex-wrap' => 'nowrap' ),
 221              );
 222          }
 223  
 224          if ( $has_block_gap_support && isset( $gap_value ) ) {
 225              $combined_gap_value = '';
 226              $gap_sides          = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' );
 227  
 228              foreach ( $gap_sides as $gap_side ) {
 229                  $process_value = is_string( $gap_value ) ? $gap_value : _wp_array_get( $gap_value, array( $gap_side ), $fallback_gap_value );
 230                  // Get spacing CSS variable from preset value if provided.
 231                  if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) {
 232                      $index_to_splice = strrpos( $process_value, '|' ) + 1;
 233                      $slug            = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) );
 234                      $process_value   = "var(--wp--preset--spacing--$slug)";
 235                  }
 236                  $combined_gap_value .= "$process_value ";
 237              }
 238              $gap_value = trim( $combined_gap_value );
 239  
 240              if ( null !== $gap_value && ! $should_skip_gap_serialization ) {
 241                  $layout_styles[] = array(
 242                      'selector'     => $selector,
 243                      'declarations' => array( 'gap' => $gap_value ),
 244                  );
 245              }
 246          }
 247  
 248          if ( 'horizontal' === $layout_orientation ) {
 249              /*
 250               * Add this style only if is not empty for backwards compatibility,
 251               * since we intend to convert blocks that had flex layout implemented
 252               * by custom css.
 253               */
 254              if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
 255                  $layout_styles[] = array(
 256                      'selector'     => $selector,
 257                      'declarations' => array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] ),
 258                  );
 259              }
 260  
 261              if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) {
 262                  $layout_styles[] = array(
 263                      'selector'     => $selector,
 264                      'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ),
 265                  );
 266              }
 267          } else {
 268              $layout_styles[] = array(
 269                  'selector'     => $selector,
 270                  'declarations' => array( 'flex-direction' => 'column' ),
 271              );
 272              if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
 273                  $layout_styles[] = array(
 274                      'selector'     => $selector,
 275                      'declarations' => array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] ),
 276                  );
 277              } else {
 278                  $layout_styles[] = array(
 279                      'selector'     => $selector,
 280                      'declarations' => array( 'align-items' => 'flex-start' ),
 281                  );
 282              }
 283              if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) {
 284                  $layout_styles[] = array(
 285                      'selector'     => $selector,
 286                      'declarations' => array( 'justify-content' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ),
 287                  );
 288              }
 289          }
 290      }
 291  
 292      if ( ! empty( $layout_styles ) ) {
 293          /*
 294           * Add to the style engine store to enqueue and render layout styles.
 295           * Return compiled layout styles to retain backwards compatibility.
 296           * Since https://github.com/WordPress/gutenberg/pull/42452,
 297           * wp_enqueue_block_support_styles is no longer called in this block supports file.
 298           */
 299          return wp_style_engine_get_stylesheet_from_css_rules(
 300              $layout_styles,
 301              array(
 302                  'context'  => 'block-supports',
 303                  'prettify' => false,
 304              )
 305          );
 306      }
 307  
 308      return '';
 309  }
 310  
 311  /**
 312   * Renders the layout config to the block wrapper.
 313   *
 314   * @since 5.8.0
 315   * @access private
 316   *
 317   * @param string $block_content Rendered block content.
 318   * @param array  $block         Block object.
 319   * @return string Filtered block content.
 320   */
 321  function wp_render_layout_support_flag( $block_content, $block ) {
 322      $block_type       = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
 323      $support_layout   = block_has_support( $block_type, array( '__experimentalLayout' ), false );
 324      $has_child_layout = isset( $block['attrs']['style']['layout']['selfStretch'] );
 325  
 326      if ( ! $support_layout && ! $has_child_layout ) {
 327          return $block_content;
 328      }
 329      $outer_class_names = array();
 330  
 331      if ( $has_child_layout && ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] || 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) ) {
 332          $container_content_class = wp_unique_id( 'wp-container-content-' );
 333  
 334          $child_layout_styles = array();
 335  
 336          if ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] && isset( $block['attrs']['style']['layout']['flexSize'] ) ) {
 337              $child_layout_styles[] = array(
 338                  'selector'     => ".$container_content_class",
 339                  'declarations' => array(
 340                      'flex-basis' => $block['attrs']['style']['layout']['flexSize'],
 341                      'box-sizing' => 'border-box',
 342                  ),
 343              );
 344          } elseif ( 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) {
 345              $child_layout_styles[] = array(
 346                  'selector'     => ".$container_content_class",
 347                  'declarations' => array(
 348                      'flex-grow' => '1',
 349                  ),
 350              );
 351          }
 352  
 353          wp_style_engine_get_stylesheet_from_css_rules(
 354              $child_layout_styles,
 355              array(
 356                  'context'  => 'block-supports',
 357                  'prettify' => false,
 358              )
 359          );
 360  
 361          $outer_class_names[] = $container_content_class;
 362      }
 363  
 364      // Return early if only child layout exists.
 365      if ( ! $support_layout && ! empty( $outer_class_names ) ) {
 366          $content = new WP_HTML_Tag_Processor( $block_content );
 367          $content->next_tag();
 368          $content->add_class( implode( ' ', $outer_class_names ) );
 369          return (string) $content;
 370      }
 371  
 372      $global_settings        = wp_get_global_settings();
 373      $global_layout_settings = _wp_array_get( $global_settings, array( 'layout' ), null );
 374      $used_layout            = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
 375  
 376      if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] && ! $global_layout_settings ) {
 377          return $block_content;
 378      }
 379  
 380      $class_names        = array();
 381      $layout_definitions = _wp_array_get( $global_layout_settings, array( 'definitions' ), array() );
 382      $container_class    = wp_unique_id( 'wp-container-' );
 383      $layout_classname   = '';
 384  
 385      // Set the correct layout type for blocks using legacy content width.
 386      if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) {
 387          $used_layout['type'] = 'constrained';
 388      }
 389  
 390      $root_padding_aware_alignments = _wp_array_get( $global_settings, array( 'useRootPaddingAwareAlignments' ), false );
 391  
 392      if (
 393          $root_padding_aware_alignments &&
 394          isset( $used_layout['type'] ) &&
 395          'constrained' === $used_layout['type']
 396      ) {
 397          $class_names[] = 'has-global-padding';
 398      }
 399  
 400      /*
 401       * The following section was added to reintroduce a small set of layout classnames that were
 402       * removed in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719). It is
 403       * not intended to provide an extended set of classes to match all block layout attributes
 404       * here.
 405       */
 406      if ( ! empty( $block['attrs']['layout']['orientation'] ) ) {
 407          $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] );
 408      }
 409  
 410      if ( ! empty( $block['attrs']['layout']['justifyContent'] ) ) {
 411          $class_names[] = 'is-content-justification-' . sanitize_title( $block['attrs']['layout']['justifyContent'] );
 412      }
 413  
 414      if ( ! empty( $block['attrs']['layout']['flexWrap'] ) && 'nowrap' === $block['attrs']['layout']['flexWrap'] ) {
 415          $class_names[] = 'is-nowrap';
 416      }
 417  
 418      // Get classname for layout type.
 419      if ( isset( $used_layout['type'] ) ) {
 420          $layout_classname = _wp_array_get( $layout_definitions, array( $used_layout['type'], 'className' ), '' );
 421      } else {
 422          $layout_classname = _wp_array_get( $layout_definitions, array( 'default', 'className' ), '' );
 423      }
 424  
 425      if ( $layout_classname && is_string( $layout_classname ) ) {
 426          $class_names[] = sanitize_title( $layout_classname );
 427      }
 428  
 429      /*
 430       * Only generate Layout styles if the theme has not opted-out.
 431       * Attribute-based Layout classnames are output in all cases.
 432       */
 433      if ( ! current_theme_supports( 'disable-layout-styles' ) ) {
 434  
 435          $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) );
 436          /*
 437           * Skip if gap value contains unsupported characters.
 438           * Regex for CSS value borrowed from `safecss_filter_attr`, and used here
 439           * to only match against the value, not the CSS attribute.
 440           */
 441          if ( is_array( $gap_value ) ) {
 442              foreach ( $gap_value as $key => $value ) {
 443                  $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value;
 444              }
 445          } else {
 446              $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value;
 447          }
 448  
 449          $fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' );
 450          $block_spacing      = _wp_array_get( $block, array( 'attrs', 'style', 'spacing' ), null );
 451  
 452          /*
 453           * If a block's block.json skips serialization for spacing or spacing.blockGap,
 454           * don't apply the user-defined value to the styles.
 455           */
 456          $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );
 457  
 458          $block_gap             = _wp_array_get( $global_settings, array( 'spacing', 'blockGap' ), null );
 459          $has_block_gap_support = isset( $block_gap );
 460  
 461          $style = wp_get_layout_style(
 462              ".$container_class.$container_class",
 463              $used_layout,
 464              $has_block_gap_support,
 465              $gap_value,
 466              $should_skip_gap_serialization,
 467              $fallback_gap_value,
 468              $block_spacing
 469          );
 470  
 471          // Only add container class and enqueue block support styles if unique styles were generated.
 472          if ( ! empty( $style ) ) {
 473              $class_names[] = $container_class;
 474          }
 475      }
 476  
 477      $content_with_outer_classnames = '';
 478  
 479      if ( ! empty( $outer_class_names ) ) {
 480          $content_with_outer_classnames = new WP_HTML_Tag_Processor( $block_content );
 481          $content_with_outer_classnames->next_tag();
 482          foreach ( $outer_class_names as $outer_class_name ) {
 483              $content_with_outer_classnames->add_class( $outer_class_name );
 484          }
 485  
 486          $content_with_outer_classnames = (string) $content_with_outer_classnames;
 487      }
 488  
 489      /**
 490      * The first chunk of innerContent contains the block markup up until the inner blocks start.
 491      * This targets the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
 492      */
 493      $inner_content_classnames = '';
 494  
 495      if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) && count( $block['innerContent'] ) > 1 ) {
 496          $tags            = new WP_HTML_Tag_Processor( $block['innerContent'][0] );
 497          $last_classnames = '';
 498          while ( $tags->next_tag() ) {
 499              $last_classnames = $tags->get_attribute( 'class' );
 500          }
 501  
 502          $inner_content_classnames = (string) $last_classnames;
 503      }
 504  
 505      $content = $content_with_outer_classnames ? new WP_HTML_Tag_Processor( $content_with_outer_classnames ) : new WP_HTML_Tag_Processor( $block_content );
 506  
 507      if ( $inner_content_classnames ) {
 508          $content->next_tag( array( 'class_name' => $inner_content_classnames ) );
 509          foreach ( $class_names as $class_name ) {
 510              $content->add_class( $class_name );
 511          }
 512      } else {
 513          $content->next_tag();
 514          foreach ( $class_names as $class_name ) {
 515              $content->add_class( $class_name );
 516          }
 517      }
 518  
 519      return (string) $content;
 520  }
 521  
 522  // Register the block support.
 523  WP_Block_Supports::get_instance()->register(
 524      'layout',
 525      array(
 526          'register_attribute' => 'wp_register_layout_support',
 527      )
 528  );
 529  add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 );
 530  
 531  /**
 532   * For themes without theme.json file, make sure
 533   * to restore the inner div for the group block
 534   * to avoid breaking styles relying on that div.
 535   *
 536   * @since 5.8.0
 537   * @access private
 538   *
 539   * @param string $block_content Rendered block content.
 540   * @param array  $block         Block object.
 541   * @return string Filtered block content.
 542   */
 543  function wp_restore_group_inner_container( $block_content, $block ) {
 544      $tag_name                         = isset( $block['attrs']['tagName'] ) ? $block['attrs']['tagName'] : 'div';
 545      $group_with_inner_container_regex = sprintf(
 546          '/(^\s*<%1$s\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/U',
 547          preg_quote( $tag_name, '/' )
 548      );
 549  
 550      if (
 551          wp_theme_has_theme_json() ||
 552          1 === preg_match( $group_with_inner_container_regex, $block_content ) ||
 553          ( isset( $block['attrs']['layout']['type'] ) && 'flex' === $block['attrs']['layout']['type'] )
 554      ) {
 555          return $block_content;
 556      }
 557  
 558      $replace_regex   = sprintf(
 559          '/(^\s*<%1$s\b[^>]*wp-block-group[^>]*>)(.*)(<\/%1$s>\s*$)/ms',
 560          preg_quote( $tag_name, '/' )
 561      );
 562      $updated_content = preg_replace_callback(
 563          $replace_regex,
 564          static function( $matches ) {
 565              return $matches[1] . '<div class="wp-block-group__inner-container">' . $matches[2] . '</div>' . $matches[3];
 566          },
 567          $block_content
 568      );
 569      return $updated_content;
 570  }
 571  
 572  add_filter( 'render_block_core/group', 'wp_restore_group_inner_container', 10, 2 );
 573  
 574  /**
 575   * For themes without theme.json file, make sure
 576   * to restore the outer div for the aligned image block
 577   * to avoid breaking styles relying on that div.
 578   *
 579   * @since 6.0.0
 580   * @access private
 581   *
 582   * @param string $block_content Rendered block content.
 583   * @param  array  $block        Block object.
 584   * @return string Filtered block content.
 585   */
 586  function wp_restore_image_outer_container( $block_content, $block ) {
 587      $image_with_align = "
 588  /# 1) everything up to the class attribute contents
 589  (
 590      ^\s*
 591      <figure\b
 592      [^>]*
 593      \bclass=
 594      [\"']
 595  )
 596  # 2) the class attribute contents
 597  (
 598      [^\"']*
 599      \bwp-block-image\b
 600      [^\"']*
 601      \b(?:alignleft|alignright|aligncenter)\b
 602      [^\"']*
 603  )
 604  # 3) everything after the class attribute contents
 605  (
 606      [\"']
 607      [^>]*
 608      >
 609      .*
 610      <\/figure>
 611  )/iUx";
 612  
 613      if (
 614          wp_theme_has_theme_json() ||
 615          0 === preg_match( $image_with_align, $block_content, $matches )
 616      ) {
 617          return $block_content;
 618      }
 619  
 620      $wrapper_classnames = array( 'wp-block-image' );
 621  
 622      // If the block has a classNames attribute these classnames need to be removed from the content and added back
 623      // to the new wrapper div also.
 624      if ( ! empty( $block['attrs']['className'] ) ) {
 625          $wrapper_classnames = array_merge( $wrapper_classnames, explode( ' ', $block['attrs']['className'] ) );
 626      }
 627      $content_classnames          = explode( ' ', $matches[2] );
 628      $filtered_content_classnames = array_diff( $content_classnames, $wrapper_classnames );
 629  
 630      return '<div class="' . implode( ' ', $wrapper_classnames ) . '">' . $matches[1] . implode( ' ', $filtered_content_classnames ) . $matches[3] . '</div>';
 631  }
 632  
 633  add_filter( 'render_block_core/image', 'wp_restore_image_outer_container', 10, 2 );


Generated : Sun Jun 4 08:20:02 2023 Cross-referenced by PHPXref