admin管理员组文章数量:1122832
What is the best practice to do this in Gutenberg/JavaScript:
update_post_meta( $page_id, '_custom_post_meta', 'Some data to be saved' );
- I need to do this from a sidebar box
- Custom meta is registered, and I can update it for currently edited post
- I need to do it for another post, not the one currently edited
Here is the use case:
const UpdateMeta = () => {
const { editPost } = useDispatch( 'core/editor' );
const onChange = ( value ) => {
editPost( { // I am updating currently edited post here, and that's fine
meta: { _custom_meta : JSON.stringify( value ) },
} );
// But, I would like to change some other post meta, selected by thID
};
return (
<FormTokenField
value={ selectedContinents }
suggestions={ suggestionsList }
__experimentalShowHowTo={false}
onChange={ onChange }
displayTransform={ prepare }
/>
);
}
const Component = () => (
<PluginDocumentSettingPanel
title={ 'My Sidebar Box' }>
<UpdateMeta/>
</PluginDocumentSettingPanel>
);
registerPlugin( 'my-plugin-name', {
icon: '',
render: Component,
} );
I excluded nonrelevant parts of the code.
Update: I am sharing full code here (code is WIP, please ignore eventual mistakes and deficiencies:
const { registerPlugin } = wp.plugins;
const { FormTokenField } = wpponents;
const { PluginDocumentSettingPanel } = wp.editPost;
const { useSelect, useDispatch } = wp.data;
const { useState } = wp.element;
let targetType = '';
const RelatedDifferentTypePosts = () => {
const postType = wp.data.select( 'core/editor' ).getCurrentPostType();
switch ( postType ) {
case 'display':
targetType = 'event';
break;
case 'event':
targetType = 'display';
break;
}
const postMetaField = `_assigned_${ targetType }s`;
const isLoading = useSelect( ( select ) => {
return select( 'core/data' ).isResolving( 'core', 'getEntityRecords', [
'postType', targetType
] );
} );
const assignedPosts = useSelect(
( select ) => select( 'core/editor' ).getEditedPostAttribute( 'meta' )[postMetaField], []
);
const targetPostsRaw = useSelect(
( select ) => select( 'core' ).getEntityRecords( 'postType', targetType ), []
);
let valueTitlePair = [];
if ( targetPostsRaw ) {
valueTitlePair = targetPostsRaw.map( ( postItem ) => {
const tempObj = {};
tempObj.id = postItem.id;
tempObj.slug = postItem.slug;
return tempObj;
} );
}
const slugs = assignedPosts ? Array.from( JSON.parse( assignedPosts ), ( item ) => { return item.slug; } ) : [];
const [ selectedPosts, setSelectedPosts ] = useState( slugs );
let suggestionsList;
if ( targetPostsRaw ) {
suggestionsList = Array.from( targetPostsRaw, ( postItem ) => {
return postItem.slug;
} );
}
const { editPost } = useDispatch( 'core/editor' );
const onChange = ( value ) => {
/* Prevent entering non existing Events */
value = value.filter( ( entry ) => suggestionsList.includes( entry ) );
setSelectedPosts( value );
value = valueTitlePair.filter( pair => value.includes( pair.slug ) );
editPost( {
meta: { [ postMetaField ] : JSON.stringify( value ) },
} );
};
const prepare = ( token ) => {
return token.replaceAll( '-', ' ' ).replace( /(^\w|\s\w)/g, m => m.toUpperCase() );
};
if ( isLoading ) {
return <h3>Loading...</h3>;
}
return (
<FormTokenField
value={ selectedPosts }
suggestions={ suggestionsList }
__experimentalShowHowTo={false}
onChange={ onChange }
displayTransform={ prepare }
/>
);
};
/**
* Component
*/
const Component = () => (
<PluginDocumentSettingPanel
title={ `Related ${ targetType.charAt( 0 ).toUpperCase() + targetType.slice( 1 ) }s` }>
<RelatedDifferentTypePosts/>
</PluginDocumentSettingPanel>
);
registerPlugin( 'related-posts-of-different-type', {
icon: '',
render: Component,
} );
What is the best practice to do this in Gutenberg/JavaScript:
update_post_meta( $page_id, '_custom_post_meta', 'Some data to be saved' );
- I need to do this from a sidebar box
- Custom meta is registered, and I can update it for currently edited post
- I need to do it for another post, not the one currently edited
Here is the use case:
const UpdateMeta = () => {
const { editPost } = useDispatch( 'core/editor' );
const onChange = ( value ) => {
editPost( { // I am updating currently edited post here, and that's fine
meta: { _custom_meta : JSON.stringify( value ) },
} );
// But, I would like to change some other post meta, selected by thID
};
return (
<FormTokenField
value={ selectedContinents }
suggestions={ suggestionsList }
__experimentalShowHowTo={false}
onChange={ onChange }
displayTransform={ prepare }
/>
);
}
const Component = () => (
<PluginDocumentSettingPanel
title={ 'My Sidebar Box' }>
<UpdateMeta/>
</PluginDocumentSettingPanel>
);
registerPlugin( 'my-plugin-name', {
icon: '',
render: Component,
} );
I excluded nonrelevant parts of the code.
Update: I am sharing full code here (code is WIP, please ignore eventual mistakes and deficiencies:
const { registerPlugin } = wp.plugins;
const { FormTokenField } = wp.components;
const { PluginDocumentSettingPanel } = wp.editPost;
const { useSelect, useDispatch } = wp.data;
const { useState } = wp.element;
let targetType = '';
const RelatedDifferentTypePosts = () => {
const postType = wp.data.select( 'core/editor' ).getCurrentPostType();
switch ( postType ) {
case 'display':
targetType = 'event';
break;
case 'event':
targetType = 'display';
break;
}
const postMetaField = `_assigned_${ targetType }s`;
const isLoading = useSelect( ( select ) => {
return select( 'core/data' ).isResolving( 'core', 'getEntityRecords', [
'postType', targetType
] );
} );
const assignedPosts = useSelect(
( select ) => select( 'core/editor' ).getEditedPostAttribute( 'meta' )[postMetaField], []
);
const targetPostsRaw = useSelect(
( select ) => select( 'core' ).getEntityRecords( 'postType', targetType ), []
);
let valueTitlePair = [];
if ( targetPostsRaw ) {
valueTitlePair = targetPostsRaw.map( ( postItem ) => {
const tempObj = {};
tempObj.id = postItem.id;
tempObj.slug = postItem.slug;
return tempObj;
} );
}
const slugs = assignedPosts ? Array.from( JSON.parse( assignedPosts ), ( item ) => { return item.slug; } ) : [];
const [ selectedPosts, setSelectedPosts ] = useState( slugs );
let suggestionsList;
if ( targetPostsRaw ) {
suggestionsList = Array.from( targetPostsRaw, ( postItem ) => {
return postItem.slug;
} );
}
const { editPost } = useDispatch( 'core/editor' );
const onChange = ( value ) => {
/* Prevent entering non existing Events */
value = value.filter( ( entry ) => suggestionsList.includes( entry ) );
setSelectedPosts( value );
value = valueTitlePair.filter( pair => value.includes( pair.slug ) );
editPost( {
meta: { [ postMetaField ] : JSON.stringify( value ) },
} );
};
const prepare = ( token ) => {
return token.replaceAll( '-', ' ' ).replace( /(^\w|\s\w)/g, m => m.toUpperCase() );
};
if ( isLoading ) {
return <h3>Loading...</h3>;
}
return (
<FormTokenField
value={ selectedPosts }
suggestions={ suggestionsList }
__experimentalShowHowTo={false}
onChange={ onChange }
displayTransform={ prepare }
/>
);
};
/**
* Component
*/
const Component = () => (
<PluginDocumentSettingPanel
title={ `Related ${ targetType.charAt( 0 ).toUpperCase() + targetType.slice( 1 ) }s` }>
<RelatedDifferentTypePosts/>
</PluginDocumentSettingPanel>
);
registerPlugin( 'related-posts-of-different-type', {
icon: '',
render: Component,
} );
Share
Improve this question
edited Sep 28, 2022 at 9:13
Tahi Reu
asked Sep 27, 2022 at 10:47
Tahi ReuTahi Reu
3081 silver badge14 bronze badges
9
|
Show 4 more comments
1 Answer
Reset to default 0I was able to do this using the Backbone JavaScript Client provided as part of the wp-api
core scripts.
You can fetch a post, update its meta, and save it. Make sure you wp_enqueue_script( 'wp-api' )
or add it to your script's dependencies so the API is available in JavaScript at wp.api
.
Example:
const post = new wp.api.models.Post( { id: 123 } );
post.fetch().done( () => {
post.setMeta( 'your_meta_field', 'your_meta_string_content' );
post.save().done( () => {
// Any actions to perform after the meta has been saved.
} );
} );
The Backbone Client methods don't have great documentation at the time of this writing, but you can inspect them in the source. For example, setMeta()
is here: https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-api.js#L543-L553
Be careful since the API returns promises for most methods; it's easy to make a mistake (e.g., trying to set the post meta before the post has been fetched, which won't do anything).
Also note that the REST API has endpoints for each post type, so you will need to use different models for each. For example, wp.api.models.Post
, wp.api.models.Page
, wp.api.models.YourCustomPostTypes
, etc. You may have to save that info along with the ID so you know which endpoint to use.
本文标签: block editorHow to edit post meta by post ID in Gutenberg
版权声明:本文标题:block editor - How to edit post meta by post ID in Gutenberg 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736287147a1927817.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
thID
in a comment but it never appears in the code. What are you trying to do that requires this? Why do you need to modify other posts that aren't the post being edited? – Tom J Nowell ♦ Commented Sep 27, 2022 at 17:37