PluginProbe
Gutenberg / 17.2.0
Gutenberg v17.2.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / experimental / blocks.php

blocks.php in Gutenberg 17.2.0, at lib/experimental/blocks.php

186 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Temporary compatibility shims for block APIs present in Gutenberg.
4 *
5 * @package gutenberg
6 */
7
8 if ( ! function_exists( 'wp_enqueue_block_view_script' ) ) {
9 /**
10 * Enqueues a frontend script for a specific block.
11 *
12 * Scripts enqueued using this function will only get printed
13 * when the block gets rendered on the frontend.
14 *
15 * @since 6.2.0
16 *
17 * @param string $block_name The block name, including namespace.
18 * @param array $args An array of arguments [handle,src,deps,ver,media,textdomain].
19 *
20 * @return void
21 */
22 function wp_enqueue_block_view_script( $block_name, $args ) {
23 $args = wp_parse_args(
24 $args,
25 array(
26 'handle' => '',
27 'src' => '',
28 'deps' => array(),
29 'ver' => false,
30 'in_footer' => false,
31
32 // Additional args to allow translations for the script's textdomain.
33 'textdomain' => '',
34 )
35 );
36
37 /**
38 * Callback function to register and enqueue scripts.
39 *
40 * @param string $content When the callback is used for the render_block filter,
41 * the content needs to be returned so the function parameter
42 * is to ensure the content exists.
43 * @return string Block content.
44 */
45 $callback = static function ( $content, $block ) use ( $args, $block_name ) {
46
47 // Sanity check.
48 if ( empty( $block['blockName'] ) || $block_name !== $block['blockName'] ) {
49 return $content;
50 }
51
52 // Register the stylesheet.
53 if ( ! empty( $args['src'] ) ) {
54 wp_register_script( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['in_footer'] );
55 }
56
57 // Enqueue the stylesheet.
58 wp_enqueue_script( $args['handle'] );
59
60 // If a textdomain is defined, use it to set the script translations.
61 if ( ! empty( $args['textdomain'] ) && in_array( 'wp-i18n', $args['deps'], true ) ) {
62 wp_set_script_translations( $args['handle'], $args['textdomain'], $args['domainpath'] );
63 }
64
65 return $content;
66 };
67
68 /*
69 * The filter's callback here is an anonymous function because
70 * using a named function in this case is not possible.
71 *
72 * The function cannot be unhooked, however, users are still able
73 * to dequeue the script registered/enqueued by the callback
74 * which is why in this case, using an anonymous function
75 * was deemed acceptable.
76 */
77 add_filter( 'render_block', $callback, 10, 2 );
78 }
79 }
80
81
82
83
84 $gutenberg_experiments = get_option( 'gutenberg-experiments' );
85 if ( $gutenberg_experiments && array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ) {
86 /**
87 * Renders the block meta attributes.
88 *
89 * @param string $block_content Block Content.
90 * @param array $block Block attributes.
91 * @param WP_Block $block_instance The block instance.
92 */
93 function gutenberg_render_block_connections( $block_content, $block, $block_instance ) {
94 $connection_sources = require __DIR__ . '/connection-sources/index.php';
95 $block_type = $block_instance->block_type;
96
97 // Allowlist of blocks that support block connections.
98 // Currently, we only allow the following blocks and attributes:
99 // - Paragraph: content.
100 // - Image: url.
101 $blocks_attributes_allowlist = array(
102 'core/paragraph' => array( 'content' ),
103 'core/image' => array( 'url' ),
104 );
105
106 // Whitelist of the block types that support block connections.
107 // Currently, we only allow the Paragraph and Image blocks to use block connections.
108 if ( ! in_array( $block['blockName'], array_keys( $blocks_attributes_allowlist ), true ) ) {
109 return $block_content;
110 }
111
112 // If for some reason, the block type is not found, skip it.
113 if ( null === $block_type ) {
114 return $block_content;
115 }
116
117 // If the block does not have support for block connections, skip it.
118 if ( ! block_has_support( $block_type, array( '__experimentalConnections' ), false ) ) {
119 return $block_content;
120 }
121
122 // Get all the attributes that have a connection.
123 $connected_attributes = $block['attrs']['connections']['attributes'] ?? false;
124 if ( ! $connected_attributes ) {
125 return $block_content;
126 }
127
128 foreach ( $connected_attributes as $attribute_name => $attribute_value ) {
129
130 // If the attribute is not in the allowlist, skip it.
131 if ( ! in_array( $attribute_name, $blocks_attributes_allowlist[ $block['blockName'] ], true ) ) {
132 continue;
133 }
134
135 // If the source value is not "meta_fields", skip it because the only supported
136 // connection source is meta (custom fields) for now.
137 if ( 'meta_fields' !== $attribute_value['source'] ) {
138 continue;
139 }
140
141 // If the attribute does not have a source, skip it.
142 if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) {
143 continue;
144 }
145
146 // If the attribute does not specify the name of the custom field, skip it.
147 if ( ! isset( $attribute_value['value'] ) ) {
148 continue;
149 }
150
151 // Get the content from the connection source.
152 $custom_value = $connection_sources[ $attribute_value['source'] ](
153 $block_instance,
154 $attribute_value['value']
155 );
156
157 $tags = new WP_HTML_Tag_Processor( $block_content );
158 $found = $tags->next_tag(
159 array(
160 // TODO: In the future, when blocks other than Paragraph and Image are
161 // supported, we should build the full query from CSS selector.
162 'tag_name' => $block_type->attributes[ $attribute_name ]['selector'],
163 )
164 );
165 if ( ! $found ) {
166 return $block_content;
167 }
168 $tag_name = $tags->get_tag();
169 $markup = "<$tag_name>$custom_value</$tag_name>";
170 $updated_tags = new WP_HTML_Tag_Processor( $markup );
171 $updated_tags->next_tag();
172
173 // Get all the attributes from the original block and add them to the new markup.
174 $names = $tags->get_attribute_names_with_prefix( '' );
175 foreach ( $names as $name ) {
176 $updated_tags->set_attribute( $name, $tags->get_attribute( $name ) );
177 }
178
179 return $updated_tags->get_updated_html();
180 }
181
182 return $block_content;
183 }
184 add_filter( 'render_block', 'gutenberg_render_block_connections', 10, 3 );
185 }
186