-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Expand file tree
/
Copy pathcustom-fields.js
More file actions
135 lines (130 loc) · 3.83 KB
/
custom-fields.js
File metadata and controls
135 lines (130 loc) · 3.83 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { PanelBody, TextControl } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import { InspectorControls } from '../components';
import { useBlockEditingMode } from '../components/block-editing-mode';
/**
* Filters registered block settings, extending attributes to include `connections`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
export function addAttribute( settings ) {
if ( hasBlockSupport( settings, 'connections', true ) ) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
connections: {
type: 'object',
},
};
}
return settings;
}
/**
* Override the default edit UI to include a new block inspector control for
* assigning a connection to blocks that has support for connections.
* Currently, only the `core/paragraph` block is supported and there is only a relation
* between paragraph content and a custom field.
*
* @param {WPComponent} BlockEdit Original component.
*
* @return {WPComponent} Wrapped component.
*/
export const withInspectorControl = createHigherOrderComponent(
( BlockEdit ) => {
return ( props ) => {
const blockEditingMode = useBlockEditingMode();
const hasCustomFieldsSupport = hasBlockSupport(
props.name,
'connections',
false
);
// We prevent that the content is lost when the user removes the custom field.
// Editing the content in the paragraph block with a placeholder is not the best solution.
const prevContent = useRef( props.attributes?.content );
if ( ! prevContent.current ) {
prevContent.current = '';
}
if ( hasCustomFieldsSupport && props.isSelected ) {
return (
<>
<BlockEdit { ...props } />
{ blockEditingMode === 'default' && (
<InspectorControls>
<PanelBody
title={ __( 'Connections' ) }
initialOpen={ true }
>
<TextControl
__nextHasNoMarginBottom
autoComplete="off"
label={ __( 'Custom field meta_key' ) }
value={
props.attributes?.connections
?.content?.value || ''
}
onChange={ ( nextValue ) => {
if ( nextValue === '' ) {
props.setAttributes( {
connections: undefined,
content:
prevContent.current !==
''
? prevContent.current
: undefined,
} );
} else {
props.setAttributes( {
connections: {
attributes: {
// Content will be variable, could be content, href, src, etc.
content: {
// Source will be variable, could be post_meta, user_meta, term_meta, etc.
// Could even be a custom source like a social media attribute.
source: 'meta_fields',
value: nextValue,
},
},
},
content: sprintf(
'This content will be replaced in the frontend by the custom field "%s" value.',
nextValue
),
} );
}
} }
/>
</PanelBody>
</InspectorControls>
) }
</>
);
}
return <BlockEdit { ...props } />;
};
},
'withInspectorControl'
);
if ( window.__experimentalConnections ) {
addFilter(
'blocks.registerBlockType',
'core/connections/attribute',
addAttribute
);
addFilter(
'editor.BlockEdit',
'core/connections/with-inspector-control',
withInspectorControl
);
}