Пользовательский блок Richtext Гутенберга, выводящий форматирование HTML в виде текста во внешнем интерфейсе веб-сайтов.

Я редактирую (плагин Testimonial Slider Block) [https://github.com/laccadive-io/testimonials-slider-blockpting, чтобы пользовательский блок имел поле Richtext, а также существующие поля открытого текста в WP.

После внесения некоторых изменений в исходный код я смог реализовать параметры форматирования в редакторе Гутенберга для настраиваемого блока. Однако параметры форматирования / HTML отображаются в веб-интерфейсе как обычный текст.

Например, если я введу «Hello World» в поле richtext и выделю его жирным шрифтом, интерфейс будет отображаться буквально (без фактического форматирования текста);

<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;
 }
});

person Eivic    schedule 24.04.2019    source источник
comment
это много кода для чтения. вы можете повысить вероятность ответов, потратив больше времени на извлечение необходимых частей.   -  person niklas    schedule 16.06.2019


Ответы (1)


Вы должны использовать ‹RichText.Content /› для правильного отображения значения из RichText. Попробуйте вместо этого:

{testimonial.content && (
    <p className="testimonial-text-container">
        <span className="testimonial-text"><RichText.Content tag={'p'} value={testimonial.content} /></span>
    </p>
)}

<RichText.Content tag={'p'} value={title} />
person Rodrigo Techera    schedule 29.10.2019