我想知道什么是以编程方式删除古腾堡块的好方法。
我有一个自定义的内容类型,我可以通过React和WP API添加的选择字段选择论坛帖子。然后将此帖子的标题和描述添加到帖子内容中。
以下是块:
/**
* BLOCK: my-forum-block
*
* Registering a basic block with Gutenberg.
* Simple block, renders and saves the same content without any interactivity.
*/
// Import CSS.
import \'./editor.scss\';
import \'./style.scss\';
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { InspectorControls } = wp.editor;
const { SelectControl } = wp.components;
const { Component } = wp.element;
class mySelectPosts extends Component {
// Method for setting the initial state.
static getInitialState( selectedPost ) {
return {
posts: [],
selectedPost: selectedPost,
post: {},
};
}
// Constructing our component. With super() we are setting everything to \'this\'.
// Now we can access the attributes with this.props.attributes
constructor() {
super( ...arguments );
this.state = this.constructor.getInitialState( this.props.attributes.selectedPost );
// Bind so we can use \'this\' inside the method.
this.getOptions = this.getOptions.bind(this);
// Load posts.
this.getOptions();
// bind it
this.onChangeSelectPost = this.onChangeSelectPost.bind(this);
}
onChangeSelectPost( value ) {
// Find the post
const post = this.state.posts.find( ( item ) => { return item.id == parseInt( value ) } );
//console.log(\'this post\');
//console.log(post);
// Set the state
this.setState( { selectedPost: parseInt( value ), post } );
// Set the attributes
this.props.setAttributes( {
selectedPost: parseInt( value ),
title: post.title.rendered,
content: post.content.rendered,
link: post.link,
due_date: post.due_date,
slug: post.slug,
});
}
/**
* Loading Posts
*/
getOptions() {
const CustomPost = wp.api.models.Post.extend( {
urlRoot: wpApiSettings.root + \'wp/v2/topic\',
defaults: {
type: \'topic\',
},
} );
const CustomPosts = wp.api.collections.Posts.extend( {
url: wpApiSettings.root + \'wp/v2/topic\',
model: CustomPost,
} );
const someCustomPosts = new CustomPosts();
/* someCustomPosts.fetch().then( ( posts ) => {
// do something with the custom posts
} ); */
return ( someCustomPosts ).fetch({ data: { \'filter\': { \'orderby\': \'title\', \'order\': \'ASC\' } } }).then( ( posts ) => {
if( posts && 0 !== this.state.selectedPost ) {
// If we have a selected Post, find that post and add it.
const post = posts.find( ( item ) => { return item.id == this.state.selectedPost } );
// This is the same as { post: post, posts: posts }
this.setState( { post, posts } );
} else {
this.setState({ posts });
}
} );
}
render() {
let options = [ { value: 0, label: __( \'Select a Post\' ) } ];
let output = __( \'Loading Posts\' );
if( this.state.posts.length > 0 ) {
const loading = __( \'We have %d posts. Choose one.\' );
output = loading.replace( \'%d\', this.state.posts.length );
this.state.posts.forEach((post) => {
options.push({value:post.id, label:post.title.rendered});
});
} else {
output = __( \'No posts found. Please create some first.\' );
}
// Checking if we have anything in the object
if( this.state.post.hasOwnProperty(\'title\') ) {
output = <div className="post">
<a href={ this.state.post.link }><h2 dangerouslySetInnerHTML={ { __html: this.state.post.title.rendered } }></h2></a>
<p dangerouslySetInnerHTML={ { __html: this.state.post.content.rendered } }></p>
</div>;
this.props.className += \' has-post\';
} else {
this.props.className += \' no-post\';
}
return [
!! this.props.isSelected && ( <InspectorControls key=\'inspector\'>
<SelectControl onChange={this.onChangeSelectPost} value={ this.props.attributes.selectedPost } label={ __( \'Select a Post\' ) } options={ options } />
</InspectorControls>
),
<div className={this.props.className}>{output}</div>
]
}
}
/**
* Register: aa Gutenberg Block.
*
* Registers a new block provided a unique name and an object defining its
* behavior. Once registered, the block is made editor as an option to any
* editor interface where blocks are implemented.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/
* @param {string} name Block name.
* @param {Object} settings Block settings.
* @return {?WPBlock} The block, if it has been successfully
* registered; otherwise `undefined`.
*/
registerBlockType( \'cgb/block-my-forum-block\', {
// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
title: __( \'Choose LearnDash Forum Topic\' ),
icon: \'shield\',
category: \'common\',
keywords: [
__( \'learndash\' ),
__( \'forum\' ),
__( \'my-forum-block\' ),
],
attributes: {
content: {
type: \'array\',
source: \'children\',
selector: \'p\',
},
title: {
type: \'string\',
selector: \'h3\'
},
link: {
type: \'string\',
selector: \'a\'
},
selectedPost: {
type: \'number\',
default: 0,
},
due_date: {
type: \'string\',
},
slug: {
type: \'string\',
},
},
/**
* The edit function describes the structure of your block in the context of the editor.
* This represents what the editor will render when the block is used.
*
* The "edit" property must be a valid function.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Component.
*/
edit: mySelectPosts,
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by Gutenberg into post_content.
*
* The "save" property must be specified and must be a valid function.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Frontend HTML.
*/
save: function( props ) {
return (
<div id = {`${props.attributes.slug}`} className="contenttype-wrapper sometopictype-discussion" data-id = {`${props.attributes.selectedPost}`}>
<div className = "heading d-flex flex-row">
<i className="contenticon fas fa-users fa-7x"></i>
<div className = "col">
<div className = "row required-discussion-text"><span className="content-name">Required Discussion <i class="far fa-calendar-alt"></i> Due: {props.attributes.due_date}</span></div>
<div className = "row"><a href={ props.attributes.link }><h3 dangerouslySetInnerHTML={ { __html: props.attributes.title } }></h3></a></div>
</div>
</div>
<div className = "row discussion-overview" dangerouslySetInnerHTML={ { __html: props.attributes.content } } ></div>
</div>
);
},
} );
但如果我删除了论坛帖子,那么该块也应该被删除。我想我可以阅读自定义帖子的内容并使用PHP
xpath
解析该块,然后将其删除,但想知道是否还有其他方法,特别是因为PHP的DOM相关函数在看到意外标记时可能会崩溃。
我了解了WP Rest API以及块本身是如何作为端点的。这让我有点困惑。这让我想到,如果块有端点,这是否意味着我可以通过API调用删除块?或者,这些端点是否仅用于块类型(如“布局我的布局块”),而不用于渲染块?
谢谢Brian
Edit:
添加的块代码