admin管理员组文章数量:1201993
I want to get the block ID of my widgets (e.g. #block-1
, which is displayed on the frontend after saving a widget) on the widgets screen in the backend. What I try to achieve is to display the ID of the widget in the toolbar so that you can easily copy it.
I currently use a custom API endpoint to receive the ID but it will trigger a request on every render (I already debounced it, but am searching for a better way).
My idea was than to subscribe to the save action of the widgets, since the ID is first available after saving the widgets screen:
const widgetIdToolbar = createHigherOrderComponent( ( BlockEdit ) => {
if ( select( 'core/editor' ).getCurrentPostType() ) {
return BlockEdit;
}
return ( props ) => {
if ( props.name === 'core/widget-area' || props.name === 'core/legacy-widget' ) {
return ( <BlockEdit { ...props } /> );
}
const [ widgetId, setWidgetId ] = useState( 0 );
subscribe( () => {
const isAutosavingPost = select( 'core/editor' ).isAutosavingPost();
const isSavingPost = select( 'core/editor' ).isSavingPost();
if ( isSavingPost || isAutosavingPost ) {
// do stuff
}
} );
return (
<>
<BlockEdit { ...props } />
</>
);
}
}, 'widgetIdToolbar' );
addFilter( 'editor.BlockEdit', 'rh-widget-toolbar/add-toolbar', widgetIdToolbar );
Unfortunately, both isAutosavingPost
and isSavingPost
always return false
. It seems they don’t apply to widgets. How to get the similar functionality for “on widgets save”?
I want to get the block ID of my widgets (e.g. #block-1
, which is displayed on the frontend after saving a widget) on the widgets screen in the backend. What I try to achieve is to display the ID of the widget in the toolbar so that you can easily copy it.
I currently use a custom API endpoint to receive the ID but it will trigger a request on every render (I already debounced it, but am searching for a better way).
My idea was than to subscribe to the save action of the widgets, since the ID is first available after saving the widgets screen:
const widgetIdToolbar = createHigherOrderComponent( ( BlockEdit ) => {
if ( select( 'core/editor' ).getCurrentPostType() ) {
return BlockEdit;
}
return ( props ) => {
if ( props.name === 'core/widget-area' || props.name === 'core/legacy-widget' ) {
return ( <BlockEdit { ...props } /> );
}
const [ widgetId, setWidgetId ] = useState( 0 );
subscribe( () => {
const isAutosavingPost = select( 'core/editor' ).isAutosavingPost();
const isSavingPost = select( 'core/editor' ).isSavingPost();
if ( isSavingPost || isAutosavingPost ) {
// do stuff
}
} );
return (
<>
<BlockEdit { ...props } />
</>
);
}
}, 'widgetIdToolbar' );
addFilter( 'editor.BlockEdit', 'rh-widget-toolbar/add-toolbar', widgetIdToolbar );
Unfortunately, both isAutosavingPost
and isSavingPost
always return false
. It seems they don’t apply to widgets. How to get the similar functionality for “on widgets save”?
- widgets are implemented as a legacy widget block that wraps around the widget to provide a compatibility layer, though in this case it shouldn't matter, the root problem is that the widgets screen is not a post editor so there is no main post to autosave. As an aside, what are you trying to do that requires this? – Tom J Nowell ♦ Commented May 11, 2022 at 10:18
- also is this on the edit widgets screen, or the customizer screen? – Tom J Nowell ♦ Commented May 11, 2022 at 10:27
- As I said, I want to get the block ID of the widgets in the backend, which is then displayed as ID in the frontend. This ID is first available after saving the widgets and not before (except for blocks that use server-side rendering). Thus I want to subscribe to the save action to get the ID directly afterwards. It’s the dedicated widgets screen I’m talking about. Will update the question accordingly. – KittMedia Commented May 11, 2022 at 10:29
- I see, what are you trying to do when this happens that requires it though? Needing the block ID is usually a sign that you're doing something wrong, or that a much simpler solution is present that you're unaware of. If you can provide the context then those can be shared, or it'll avoid unnecessary questions. It's also possible that someone will provide an answer that while technically correct, can't be used in your situation. – Tom J Nowell ♦ Commented May 11, 2022 at 10:39
- Also, where did you put the subscribe code in your question? Is it enqueued on that page or is it included some other way only when that widget runs? Or on a particular event? Are you trying to use the block ID to traverse upwards or across or to get the sidebar ID? – Tom J Nowell ♦ Commented May 11, 2022 at 11:09
1 Answer
Reset to default 0If the goal is to display the block ID so that the user can get it easily, instead try using a block editor filter to add a panel in the sidebar:
From: https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/#editor-blockedit
const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
return (
<Fragment>
<BlockEdit { ...props } />
<InspectorControls>
<PanelBody>My custom control</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withInspectorControl' );
wp.hooks.addFilter(
'editor.BlockEdit',
'my-plugin/with-inspector-controls',
withInspectorControls
);
Then inside the panel, use props
to retrieve the blocks ID and display it, perhaps in an input with the disabled
property. Specifically clientId
.
It might look like this (untested):
const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const withWidgetIDPanel = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
const widgetID = props.__internalWidgetId ? props.__internalWidgetId : 0;
return (
<Fragment>
<BlockEdit { ...props } />
<InspectorControls>
<PanelBody>
<input
class="components-text-control__input"
type="text"
disabled
value={ props.widgetID }
/>
</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withWidgetIDPanel' );
wp.hooks.addFilter(
'editor.BlockEdit',
'tomjn/display-widget-id',
withWidgetIDPanel
);
This will give you the widget ID if it's available in the sidebar for every legacy widget if enqueued on the widgets page, and provides a useful debug panel for non-widget editors too. It also gives you a place to use react hooks and other WordPress APIs in the context of a specific block, without needing to figure out which widget belongs to which block ID.
Note that when the widget ID changes, React will re-render the component automatically, no subscription is necessary. Note that no local state is in use.
Frontend Block ID
If however you want the ID that gets used on the frontend, there's an attribute named __internalWidgetId
. When this changes React will re-render the edit component because its props have changed, so no subscription to the store is necessary.
Before the widget is saved, this __internalWidgetId
attribute does not exist, and will be null
if accessed, and when it comes into existence again the edit component will re-render because changed props are how React knows to re-render a DOM element.
Storing the widget ID in local state is not necessary and could lead to problems. Just pass the raw attribute down if it's not null to any child components that need it or use the internal widget ID directly.
As a bonus, you can select on the core/edit-widgets
store to grab the widget data directly.
本文标签: block editorisSavingPost() for widgets
版权声明:本文标题:block editor - isSavingPost() for widgets 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738592252a2101578.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论