-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
blocks.php
122 lines (106 loc) · 4.02 KB
/
blocks.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
/**
* Temporary compatibility shims for block APIs present in Gutenberg.
*
* @package gutenberg
*/
/**
* Shim for the `variation_callback` block type argument.
*
* @param array $args The block type arguments.
* @return array The updated block type arguments.
*/
function gutenberg_register_block_type_args_shim( $args ) {
if ( isset( $args['variation_callback'] ) && is_callable( $args['variation_callback'] ) ) {
$args['variations'] = call_user_func( $args['variation_callback'] );
unset( $args['variation_callback'] );
}
return $args;
}
if ( ! method_exists( 'WP_Block_Type', 'get_variations' ) ) {
add_filter( 'register_block_type_args', 'gutenberg_register_block_type_args_shim' );
}
/**
* Registers the metadata block attribute for all block types.
*
* @param array $args Array of arguments for registering a block type.
* @return array $args
*/
function gutenberg_register_metadata_attribute( $args ) {
// Setup attributes if needed.
if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
$args['attributes'] = array();
}
if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
$args['attributes']['metadata'] = array(
'type' => 'object',
);
}
return $args;
}
add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' );
if ( ! function_exists( 'gutenberg_process_block_bindings' ) ) {
/**
* Process the block bindings attribute.
*
* @param string $block_content Block Content.
* @param array $block Block attributes.
* @param WP_Block $block_instance The block instance.
*/
function gutenberg_process_block_bindings( $block_content, $block, $block_instance ) {
// Allowed blocks that support block bindings.
// TODO: Look for a mechanism to opt-in for this. Maybe adding a property to block attributes?
$allowed_blocks = array(
'core/paragraph' => array( 'content' ),
'core/heading' => array( 'content' ),
'core/image' => array( 'url', 'title', 'alt' ),
'core/button' => array( 'url', 'text', 'linkTarget' ),
);
// If the block doesn't have the bindings property or isn't one of the allowed block types, return.
if ( ! isset( $block['attrs']['metadata']['bindings'] ) || ! isset( $allowed_blocks[ $block_instance->name ] ) ) {
return $block_content;
}
/*
* Assuming the following format for the bindings property of the "metadata" attribute:
*
* "bindings": {
* "title": {
* "source": "core/post-meta",
* "args": { "key": "text_custom_field" }
* },
* "url": {
* "source": "core/post-meta",
* "args": { "key": "url_custom_field" }
* }
* }
*/
$block_bindings_sources = wp_block_bindings_get_sources();
$modified_block_content = $block_content;
foreach ( $block['attrs']['metadata']['bindings'] as $binding_attribute => $binding_source ) {
// If the attribute is not in the list, process next attribute.
if ( ! in_array( $binding_attribute, $allowed_blocks[ $block_instance->name ], true ) ) {
continue;
}
// If no source is provided, or that source is not registered, process next attribute.
if ( ! isset( $binding_source['source'] ) || ! is_string( $binding_source['source'] ) || ! isset( $block_bindings_sources[ $binding_source['source'] ] ) ) {
continue;
}
$source_callback = $block_bindings_sources[ $binding_source['source'] ]['apply'];
// Get the value based on the source.
if ( ! isset( $binding_source['args'] ) ) {
$source_args = array();
} else {
$source_args = $binding_source['args'];
}
$source_value = $source_callback( $source_args, $block_instance, $binding_attribute );
// If the value is null, process next attribute.
if ( is_null( $source_value ) ) {
continue;
}
// Process the HTML based on the block and the attribute.
$modified_block_content = gutenberg_block_bindings_replace_html( $modified_block_content, $block_instance->name, $binding_attribute, $source_value );
}
return $modified_block_content;
}
}
add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 );