|
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 * 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 */ |
|
42 function 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. |
|
99 WP_Block_Supports::get_instance()->register( |
|
100 'layout', |
|
101 array( |
|
102 'register_attribute' => 'wp_register_layout_support', |
|
103 ) |
|
104 ); |
|
105 add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 ); |
|
106 |
|
107 /** |
|
108 * For themes without theme.json file, make sure |
|
109 * to restore the inner div for the group block |
|
110 * to avoid breaking styles relying on that div. |
|
111 * |
|
112 * @since 5.8.0 |
|
113 * @access private |
|
114 * |
|
115 * @param string $block_content Rendered block content. |
|
116 * @param array $block Block object. |
|
117 * |
|
118 * @return string Filtered block content. |
|
119 */ |
|
120 function wp_restore_group_inner_container( $block_content, $block ) { |
|
121 $group_with_inner_container_regex = '/(^\s*<div\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/'; |
|
122 |
|
123 if ( |
|
124 'core/group' !== $block['blockName'] || |
|
125 WP_Theme_JSON_Resolver::theme_has_support() || |
|
126 1 === preg_match( $group_with_inner_container_regex, $block_content ) |
|
127 ) { |
|
128 return $block_content; |
|
129 } |
|
130 |
|
131 $replace_regex = '/(^\s*<div\b[^>]*wp-block-group[^>]*>)(.*)(<\/div>\s*$)/ms'; |
|
132 $updated_content = preg_replace_callback( |
|
133 $replace_regex, |
|
134 function( $matches ) { |
|
135 return $matches[1] . '<div class="wp-block-group__inner-container">' . $matches[2] . '</div>' . $matches[3]; |
|
136 }, |
|
137 $block_content |
|
138 ); |
|
139 return $updated_content; |
|
140 } |
|
141 |
|
142 add_filter( 'render_block', 'wp_restore_group_inner_container', 10, 2 ); |