我正在编辑(推荐滑块块插件)[ https://github.com/laccadive-io/testimonials-slider-block]以允许自定义块具有富文本字段以及 WP 中现有的纯文本字段。
在对原始代码进行一些更改后,我能够在 Gutenberg 编辑器中为自定义块实现格式化选项。但是,格式选项/HTML 在网站前端显示为纯文本。
例如,如果我在富文本字段中输入“Hello World”并将其设为粗体,前端将按字面意思显示(没有实际格式化文本);
<strong>Hello World</strong>
这是编辑后的slider.js 文件,用于处理自定义块的前端和后端部分。
/**
* BLOCK: my-block
*
* Registering a basic block with Gutenberg.
* Simple block, renders and saves the same content without any interactivity.
*/
// Import CSS.
import "./style.scss";
import "./editor.scss";
const __ = wp.i18n.__; // The __() for internationalization.
const registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.
const { RichText, PlainText } = wp.editor;
/**
* Register: a 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("gts/testimonials-slider-block", {
// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
title: __("Text Carousel"), // Block title.
icon: "format-quote", // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: "common", // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
keywords: [__("Text Carousel"), __("gts")],
attributes: {
id: {
source: "attribute",
selector: ".carousel.slide",
attribute: "id"
},
testimonials: {
source: "query",
default: [],
selector: "blockquote.testimonial",
query: {
index: {
source: "text",
selector: "span.testimonial-index"
},
content: {
type: "string",
source: "text",
selector: "span.testimonial-text"
},
author: {
source: "text",
selector: "span.testimonial-author span"
}
}
}
},
/**
* 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/
*/
// The "edit" property must be a valid function.
edit: props => {
const { testimonials } = props.attributes;
if (!props.attributes.id) {
const id = `testimonial${Math.floor(Math.random() * 100)}`;
props.setAttributes({
id
});
}
const testimonialsList = testimonials
.sort((a, b) => a.index - b.index)
.map(testimonial => {
return (
<div className="gts-testimonial-block">
<p>
<span>
Insert Text Block {Number(testimonial.index) + 1} Here:
</span>
<span
className="remove-testimonial"
onClick={() => {
const newTestimonials = testimonials
.filter(item => item.index != testimonial.index)
.map(t => {
if (t.index > testimonial.index) {
t.index -= 1;
}
return t;
});
props.setAttributes({
testimonials: newTestimonials
});
}}
>
<i className="fa fa-times" />
</span>
</p>
<div className="row">
<div className="col-9 mt-3">
<PlainText
className="author-plain-text"
placeholder="Header"
value={testimonial.author}
onChange={author => {
const newObject = Object.assign({}, testimonial, {
author: author
});
props.setAttributes({
testimonials: [
...testimonials.filter(
item => item.index != testimonial.index
),
newObject
]
});
}}
/>
</div>
</div>
<blockquote className="wp-block-quote">
{/* <label>Content:</label> */}
<RichText
className="content-plain-text"
placeholder="Main Text"
value={testimonial.content}
autoFocus
onChange={content => {
const newObject = Object.assign({}, testimonial, {
content: content
});
props.setAttributes({
testimonials: [
...testimonials.filter(
item => item.index != testimonial.index
),
newObject
]
});
}}
/>
</blockquote>
</div>
);
});
return (
<div className={props.className}>
{testimonialsList}
<button
className="add-more-testimonial"
onClick={content =>
props.setAttributes({
testimonials: [
...props.attributes.testimonials,
{
index: props.attributes.testimonials.length,
content: "",
author: "",
link: ""
}
]
})
}
>
+
</button>
</div>
);
},
/**
* 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/
*/
save: props => {
const { id, testimonials } = props.attributes;
const carouselIndicators = testimonials.map(function(testimonial, index) {
return (
<li
data-target={"#" + id}
data-slide-to={index}
className={testimonial.index == 0 ? "active" : ""}
/>
);
});
const testimonialsList = testimonials.map(function(testimonial) {
const carouselClass =
testimonial.index == 0 ? "carousel-item active" : "carousel-item";
return (
<div className={carouselClass} key={testimonial.index}>
<blockquote className="testimonial">
<span className="testimonial-index" style={{ display: "none" }}>
{testimonial.index}
</span>
<div className="row">
<div className="testimonial-author-container">
{testimonial.author && (
<p className="testimonial-author-name">
{testimonial.author}
</p>
)}
</div>
</div>
{testimonial.content && (
<p className="testimonial-text-container">
<span className="testimonial-text"><p>{testimonial.content}</p></span>
</p>
)}
</blockquote>
</div>
);
});
if (testimonials.length > 0) {
return (
<div className="testimonial-slider">
<div className="carousel slide" data-ride="carousel" id={id}>
<ol className="carousel-indicators">{carouselIndicators}</ol>
<div className="carousel-inner w-75 mx-auto">
{testimonialsList}
</div>
<a
class="carousel-control-prev"
href={"#" + id}
role="button"
data-slide="prev"
>
<span class="carousel-control-prev-icon" aria-hidden="true">
<i className="fa fa-chevron-left" />
</span>
<span class="sr-only">Previous</span>
</a>
<a
class="carousel-control-next"
href={"#" + id}
role="button"
data-slide="next"
>
<span class="carousel-control-next-icon" aria-hidden="true">
<i className="fa fa-chevron-right" />
</span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
);
} else return null;
}
});