Использование данных ajax в Gutenberg InspectorControls

Я создаю пользовательский блок редактора Гутенберга, чтобы установить идентификатор видео на YouTube <button> дань data-video=""

ОБНОВЛЕНИЕ - Добавлен рабочий код ниже

Мой код function.php

// Include Css and js block files
function designa_youtube_block() {
    // Scripts
    wp_register_script(
        'youtube-block-script', // Handle.
         '/wp-content/themes/twentyfifteen/init/block.js',
        array( 'wp-blocks', 'wp-element', 'wp-i18n' ),
        time()
    );
    // Styles
    wp_register_style(
        'youtube-block-editor-style', // Handle.
        '/wp-content/themes/twentyfifteen/init/editor.css',
        array( 'wp-edit-blocks' ),
        time()
    );
    // Register the block with WP using our namespacing
    register_block_type( 'designa/youtube-block', array(
        'editor_script' => 'youtube-block-script',
        'editor_style' => 'youtube-block-editor-style',
    ) );

}
add_action( 'init', 'designa_youtube_block' );

Мой код block.js

( function( editor, components, element ) {
 const el = element.createElement;
 const registerBlockType = wp.blocks.registerBlockType;

    const RichText = wp.editor.RichText;
 const BlockControls = wp.editor.BlockControls;
 const InspectorControls = wp.editor.InspectorControls;
    const AlignmentToolbar = wp.editor.AlignmentToolbar;
 const UrlInput = wp.editor.URLInput;


    function getVideoId(url) {
        if (url) {
            let match = url.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
            
            if (match && match[2].length == 11)
                 return match[2];
            else
                return false;
        } else {
            return false;
        }
    }


 registerBlockType( 'designa/youtube-block', {
  title: 'YouTube',
  description: 'Видео в всплывающем окне.',
  icon: 'video-alt3',
  category: 'common',
  
  attributes: {
            content: {
       type: 'string',
            },
            url: {
                type: 'string',
            },
   alignment: {
    type: 'string',
   },
  },


  edit: function( props, isSelected ) {

   let attributes = props.attributes,
                url = props.attributes.url,
                alignment = props.attributes.alignment;
                
   function onChangeAlignment( newAlignment ) {
    props.setAttributes( { alignment: newAlignment } );
   }
            
            if (url)
                videoTitle();
            
            async function videoTitle(){
                    
                    let id = getVideoId(url);

                    const response = await fetch( `https://www.googleapis.com/youtube/v3/videos?id=${ id }&key=AIzaSyBUqaVKkqdXzPQnfuuP8VPa-yqOQlJwV-w&fields=items(snippet(title))&part=snippet`, {
                        cache: 'no-cache',
                        headers: {
                            'user-agent': 'WP Block',
                            'content-type': 'application/json'
                          },
                        method: 'GET',
                        redirect: 'follow', 
                        referrer: 'no-referrer', 
                    })
                    .then(
                        returned => {
                            if (returned.ok) return returned;
                            throw new Error('Network response was not ok.');
                        }
                    );
            
                    let data = await response.json();
            
                    props.setAttributes( { title: data.items[0].snippet.title} );
            
            };


   return [
    el( BlockControls, { key: 'controls' },
     el( AlignmentToolbar, {
      value: alignment,
      onChange: onChangeAlignment,
     } )
    ),
    
    el( InspectorControls, { key: 'inspector' },
     el( components.PanelBody, {
      title: 'Превью видео',
      className: 'youtube-preview-block',
      initialOpen: true,
     },
     
     el( 'div', {
         className: 'youtube-preview',
         },
      el( 'iframe', {
                            frameborder: '0',
                            allowfullscreen: 'allowfullscreen',
                            src: url ? 'https://www.youtube.com/embed/'+getVideoId(url)+'?rel=0&amp;showinfo=0' : ''
                            },
                        ),
                        
     ),
     
      el( 'div', { className: !props.attributes.title ? 'sceleton-youtube-title' : '' },
          props.attributes.title ? props.attributes.title : ''
                        ),
     
     ),
    ),

    el( 'div', { className: alignment ? props.className+' justify-content-'+alignment : props.className },

                    el( 'svg', { className: 'play-icon', width: '50', height: '50', viewBox: '0 0 70 70' },
      el( 'path', { fill: '#f6155e', d: "M35 70C54.33 70 70 54.33 70 35C70 15.67 54.33 0 35 0C15.67 0 0 15.67 0 35C0 54.33 15.67 70 35 70Z" } ),
      el( 'path', { fill: '#fff', d: "M48.2988 35L28.6988 44.1L28.6988 25.9L48.2988 35Z" } ),
     ),

                    el( 'div', { className: 'youtube-wrap' },
      el( RichText, {
                                tagName: 'div',
                                placeholder: 'Введите текст кнопки',
                                keepPlaceholderOnFocus: true,
                                isSelected: false,
                                value: props.attributes.content,
                       onChange: function( content ) {
                        props.setAttributes( {
                            content: content,
                        } );
                       }
                            }
         ),
                        
                        el( 'div', { className: 'youtube-link-wrap' },
                            
                            el( 'svg', { className: 'dashicon dashicons-admin-links', width: '20', height: '20' },
                                el( 'path', { d: "M17.74 2.76c1.68 1.69 1.68 4.41 0 6.1l-1.53 1.52c-1.12 1.12-2.7 1.47-4.14 1.09l2.62-2.61.76-.77.76-.76c.84-.84.84-2.2 0-3.04-.84-.85-2.2-.85-3.04 0l-.77.76-3.38 3.38c-.37-1.44-.02-3.02 1.1-4.14l1.52-1.53c1.69-1.68 4.42-1.68 6.1 0zM8.59 13.43l5.34-5.34c.42-.42.42-1.1 0-1.52-.44-.43-1.13-.39-1.53 0l-5.33 5.34c-.42.42-.42 1.1 0 1.52.44.43 1.13.39 1.52 0zm-.76 2.29l4.14-4.15c.38 1.44.03 3.02-1.09 4.14l-1.52 1.53c-1.69 1.68-4.41 1.68-6.1 0-1.68-1.68-1.68-4.42 0-6.1l1.53-1.52c1.12-1.12 2.7-1.47 4.14-1.1l-4.14 4.15c-.85.84-.85 2.2 0 3.05.84.84 2.2.84 3.04 0z" } ),
                            ),
                            
          el( UrlInput, {
                                    tagName: 'div',
                                    value: url,
                                    autoFocus: false,
                                    onChange: function( url ) {
                                        props.setAttributes({
                                            url: url,
                                            title: ''
                                        });
                                    }
                                }
             ),
             
             
         ),
                    ),
                    

    ),
    
   ];
   
  },


  save: function( props ) {
   let attributes = props.attributes;
            
   return (
    el( 'div', {
     className: (attributes.alignment) ? 'justify-content-'+attributes.alignment : '',
    },
    
     el( 'button', {
             className: 'video-btn',
          'data-video': getVideoId(attributes.url),
      }, attributes.content,
     ),

    )
   );
  },
  
 } );

} )(
 window.wp.editor,
 window.wp.components,
 window.wp.element,
);

Мой код editor.css

.youtube-wrap {
    width: calc(80% - 70px);
}
.wp-block-designa-youtube-block {
    display: flex;
    align-items: center;
}
.youtube-link-wrap {
    display: flex;
    align-items: center;
}
.youtube-link-wrap svg {
    margin-right: 10px;
    fill: #8f98a1;
}
.youtube-wrap {
    padding: 0 20px;
}
.youtube-preview {
 position: relative;
 padding-bottom: 56.25%;
 height: 0;
    background: #e1e9ee;
    margin-bottom: 14px;
}
.gutenberg__editor .youtube-preview iframe {
 position: absolute;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
}
.justify-content-center {
    justify-content: center;
}
.justify-content-left {
    justify-content: flex-start;
}
.justify-content-right {
    justify-content: flex-end;
}
.sceleton-youtube-title:before, .sceleton-youtube-title:after {
    content: "";
    display: block;
    height: 18px;
    width: 100%;
    background-color: #f0f4f6;
    margin-bottom: 10px;
}
.sceleton-youtube-title:after {
    width: 40%;
}
.components-panel__body.youtube-preview-block {
    font-weight: bold;
    color: #5a5e61;
    letter-spacing: 0.015em;
    line-height: 22px;
}

В конце я получил этот результат:

Все отлично работает, но теперь мне нужно получить название и продолжительность видео с YouTube по идентификатору getId(attributes.url) и вставить в блок InspectorControls.

Если я пытаюсь получить заголовок и длительность с помощью Ajax, сначала визуализирую все поля блока в InspectorControls, а затем выполняю мой запрос ajax. Мне нужно что-то подобное на AJAX успешно push( el( 'p', {}, '**YouTube Title**') )

Подскажите, как добавить информацию, полученную с помощью Ajax, в InspectorControls после рендеринга и при изменении?

0 ответов

Другие вопросы по тегам