我正在创建自定义 Gutenberg 编辑器块以将 YouTube 视频 ID 设置为<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&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;
}
一切正常,但现在我需要通过 ID 从 YouTube 获取视频的标题和持续时间getId(attributes.url)
并插入到 InspectorControls 块。
如果我尝试使用 Ajax 获取标题和持续时间,首先将所有块字段呈现给 InspectorControls,然后执行我的 ajax 请求。我在ajax成功时需要类似的东西push( el( 'p', {}, '**YouTube Title**') )
告诉我如何在渲染和更改后将使用 Ajax 获得的信息添加到 InspectorControls?