Second post/question这是我的第三个(希望是最后一个)问题。除了将数据保存到WP数据库中,我的一切都正常工作。顺便提一句this tutorial 是一座金矿,有助于了解事物如何以新的古腾堡方式工作,以及所有不同的部分如何组合在一起并相互作用。如前所述(参见上面的链接),我正在标准post editor侧栏中定制特色图像块。以下是我的截图:
单击复选框时,将显示文本字段。当你取消选中它时,它就会消失。您可以在字段中键入文本,页面将按照其应有的方式完成所有工作动作。保存时,会收到一条“成功”消息。但是,没有任何内容保存到数据库中,这是我的问题。我对数据库有独立的SQL访问权限,对于我用元数据创建的任何测试帖子,wp\\u postmeta表中都没有应该保存的内容。我可以单击复选框,在文本字段中输入一些内容,然后在调试控制台中执行以下操作,以查看数据存储中是否有我的信息:
wp.data.select(\'core/editor\').getEditedPostAttribute(\'meta\')
返回。。。Object { _featured_image_video_url: "this is a test", _featured_image_is_video: true }
正如所料。但是如果保存页面并查看数据库,就没有什么乐趣了。那里什么都没有。
下面是我当前的JavaScript代码
const el = wp.element.createElement;
const { setState, withSelect, dispatch, select} = wp.data;
const { CheckboxControl, TextControl } = wp.components;
const { useState } = wp.element;
const { withState } = wp.compose;
const { __ } = wp.i18n;
//this replaces the default with our custom Featured Image code
wp.hooks.addFilter(
\'editor.PostFeaturedImage\',
\'dsplugin/featured-image-as-video\',
wrapPostFeaturedImage
);
//create a checkbox that takes properties
const MyCheckboxControl = (props) => {
const [ isChecked, setChecked ] = useState( false );
return(
<CheckboxControl
label={ __("Image is a video", "dsplugin") }
checked={ isChecked }
onChange={ () =>{
if (isChecked){
setChecked(false);
dispatch(\'core/editor\').editPost({meta: {_featured_image_is_video: false}})
}else{
setChecked(true);
dispatch(\'core/editor\').editPost({meta: {_featured_image_is_video: true}})
}
props.onChange.call();
} }
/>
)
};
// //this the std TextControl from the example in the documentation
// const MyTextControl = withState({ videoURL: \'\', }) (({ videoURL, setState }) => (
// <TextControl
// // label="Video URL to use with featured image"
// value={ videoURL }
// placeholder={ __("Enter video URL to play when clicked", "dsplugin") }
// onChange={ ( videoURL ) => {
// //update the text field
// setState( { videoURL } );
//
// //save the new value to the DB
// // meta.featured_image_video_url = videoURL;
// // withDispach( \'core/editor\' ).editPost( {meta});
// } }
// />
// ) );
class MyTextControl extends wp.element.Component{
constructor(){
super()
this.state = {
videoURL: \'\'
}
}
render() {
const { videoURL, setState} = this.props;
// const videoURL = select(\'core/editor\').getEditedPostAttribute(\'meta\').featured_image_video_url;
return(
<TextControl
// select(\'core/editor\').getEditedPostAttribute(\'meta\').featured_image_video_url }
value={ videoURL }
placeholder={ __("Enter video URL to play when clicked", "dsplugin") }
onChange={ ( videoURL ) => {
//save the new value to the DB
const currentMeta = select( \'core/editor\' ).getEditedPostAttribute( \'meta\' );
const newMeta = { ...currentMeta, _featured_image_video_url: videoURL };
dispatch(\'core/editor\').editPost({meta: newMeta})
} }
/>
)
}
};
//we put it all together in a wrapper component with a custom state to show/hide the TextControl
class MyFeaturedImageControls extends wp.element.Component{
constructor(){
super()
this.state = {
isHidden: true
}
}
toggleHidden(){
this.setState({
isHidden: !this.state.isHidden
})
}
render() {
return(
<div>
<h4>{ __("Image Options", "dsplugin") }</h4>
<MyCheckboxControl onChange={this.toggleHidden.bind(this)}/>
{ !this.state.isHidden && <MyTextControl /> }
</div>
)
}
};
//here\'s the function that wraps the original Featured Image content and adds
//our custom controls below
function wrapPostFeaturedImage( OriginalComponent ) {
// Get meta field information from the DB.
let meta = select( \'core/editor\' ).getCurrentPostAttribute( \'meta\' );
console.log ("metadata follows:");
console.log(meta);
return function( props ) {
return (
el(
wp.element.Fragment,
{},
// \'Prepend above\',
el(
OriginalComponent,
props
),
<MyFeaturedImageControls />
)
);
}
}
以及支持它的PHP代码://add metadata fields for use with featured image metabox
function register_resource_item_featured_image_metadata() {
register_meta(
\'post\',
\'_featured_image_video_url\',
array(
\'object_subtype\' => \'ds_resource_item\',
\'show_in_rest\' => true, #must be true to work in Guttenberg
\'type\' => \'string\',
\'single\' => true,
\'sanitize_callback\' => \'sanitize_text_field\',
\'auth_callback\' => function() {
return current_user_can(\'edit_posts\');
}
)
);
register_meta(
\'post\',
\'_featured_image_is_video\',
array(
\'object_subtype\' => \'ds_resource_item\',
\'show_in_rest\' => true, #must be true to work in Guttenberg
\'single\' => true,
// \'sanitize_callback\' => \'rest_sanitize_boolean\',
\'type\' => \'boolean\',
// \'auth_callback\' => function() {
// return current_user_can(\'edit_posts\');
// }
)
);
}
add_action( \'init\', \'register_resource_item_featured_image_metadata\' );
再次。。。由于对这一切都很陌生,我想我遗漏了一些小细节。我意识到我的代码不完整,您将看到出于调试目的而注释掉的一些内容。但就目前情况而言,我认为我至少应该根据现在的数据将新输入的值保存到DB中。我还意识到,我仍然需要编写代码,以便从db中获取初始值并填充文本字段。但首先要做的事。谢谢你的帮助。
Update:下面是php代码,它定义了我在代码中使用的自定义帖子类型:
$args = array(
"label" => __( "Resource Items", "dstheme" ),
"labels" => $labels,
"description" => "DS Resource Items are the foundational content type for resources.",
"public" => true,
"publicly_queryable" => true,
"show_ui" => true,
"delete_with_user" => false,
"show_in_rest" => true,
"rest_base" => "dsr_item",
"rest_controller_class" => "WP_REST_Posts_Controller",
"has_archive" => false,
"show_in_menu" => true,
"show_in_nav_menus" => true,
"exclude_from_search" => false,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => false,
//modify the slug below to change what shows in the URL when an DSResourceItem is accessed
"rewrite" => array( "slug" => "resource-item", "with_front" => true ),
"query_var" => true,
"menu_position" => 5,
"menu_icon" => "dashicons-images-alt2",
"supports" => array( "title", "editor", "thumbnail", "custom-fields" ),
"taxonomies" => array( "post_tag" ),
);
register_post_type( "ds_resource_item", $args );