Make WordPress Core


Ignore:
Timestamp:
05/25/2021 07:35:56 AM (3 years ago)
Author:
youknowriad
Message:

Block Editor: Add the layout block support.

The layout block allows containers to define the size of their inner blocks
and the allowed allignments.
It's only enabled for themes with theme.json files.

Props nosolosw.
See #53175.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-supports/layout.php

    r50929 r50991  
    66 * @since 5.8.0
    77 */
     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 */
     17function 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 * Renders the layout config to the block wrapper.
     34 *
     35 * @since 5.8.0
     36 * @access private
     37 *
     38 * @param  string $block_content Rendered block content.
     39 * @param  array  $block         Block object.
     40 * @return string                Filtered block content.
     41 */
     42function wp_render_layout_support_flag( $block_content, $block ) {
     43    $block_type     = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
     44    $support_layout = block_has_support( $block_type, array( '__experimentalLayout' ), false );
     45    if ( ! $support_layout || ! isset( $block['attrs']['layout'] ) ) {
     46        return $block_content;
     47    }
     48
     49    $used_layout = $block['attrs']['layout'];
     50    if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
     51        $tree           = WP_Theme_JSON_Resolver::get_merged_data();
     52        $default_layout = _wp_array_get( $tree->get_settings(), array( 'layout' ) );
     53        if ( ! $default_layout ) {
     54            return $block_content;
     55        }
     56        $used_layout = $default_layout;
     57    }
     58
     59    $id           = uniqid();
     60    $content_size = isset( $used_layout['contentSize'] ) ? $used_layout['contentSize'] : null;
     61    $wide_size    = isset( $used_layout['wideSize'] ) ? $used_layout['wideSize'] : null;
     62
     63    $all_max_width_value  = $content_size ? $content_size : $wide_size;
     64    $wide_max_width_value = $wide_size ? $wide_size : $content_size;
     65
     66    // Make sure there is a single CSS rule, and all tags are stripped for security.
     67    $all_max_width_value  = safecss_filter_attr( explode( ';', $all_max_width_value )[0] );
     68    $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] );
     69
     70    $style = '';
     71    if ( $content_size || $wide_size ) {
     72        $style  = ".wp-container-$id > * {";
     73        $style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';';
     74        $style .= 'margin-left: auto !important;';
     75        $style .= 'margin-right: auto !important;';
     76        $style .= '}';
     77
     78        $style .= ".wp-container-$id > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}';
     79
     80        $style .= ".wp-container-$id .alignfull { max-width: none; }";
     81    }
     82
     83    $style .= ".wp-container-$id .alignleft { float: left; margin-right: 2em; }";
     84    $style .= ".wp-container-$id .alignright { float: right; margin-left: 2em; }";
     85
     86    // This assumes the hook only applies to blocks with a single wrapper.
     87    // I think this is a reasonable limitation for that particular hook.
     88    $content = preg_replace(
     89        '/' . preg_quote( 'class="', '/' ) . '/',
     90        'class="wp-container-' . $id . ' ',
     91        $block_content,
     92        1
     93    );
     94
     95    return $content . '<style>' . $style . '</style>';
     96}
     97
     98// Register the block support.
     99WP_Block_Supports::get_instance()->register(
     100    'layout',
     101    array(
     102        'register_attribute' => 'wp_register_layout_support',
     103    )
     104);
     105add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 );
    8106
    9107/**
     
    23121    $group_with_inner_container_regex = '/(^\s*<div\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/';
    24122
    25     // TODO: Add check for theme.json presence.
    26123    if (
    27124        'core/group' !== $block['blockName'] ||
     125        WP_Theme_JSON_Resolver::theme_has_support() ||
    28126        1 === preg_match( $group_with_inner_container_regex, $block_content )
    29127    ) {
Note: See TracChangeset for help on using the changeset viewer.