Javascript 使用ESNEXT的古腾堡中继器块
我一直在努力创建我自己的自定义古腾堡中继器块与文本和链接输入字段。我只见过像和这样的ES5样本。我已经花了将近8个小时来创建我自己版本的这些示例,我被卡住了 我在这里是因为我想被指向正确的方向(非常需要帮助) 这是我目前拥有的代码。我不知道从哪里开始ES5->ESNEXT转换 编辑:我忘了说我正试图避免使用ACF来做这件事Javascript 使用ESNEXT的古腾堡中继器块,javascript,wordpress,jsx,wordpress-gutenberg,gutenberg-blocks,Javascript,Wordpress,Jsx,Wordpress Gutenberg,Gutenberg Blocks,我一直在努力创建我自己的自定义古腾堡中继器块与文本和链接输入字段。我只见过像和这样的ES5样本。我已经花了将近8个小时来创建我自己版本的这些示例,我被卡住了 我在这里是因为我想被指向正确的方向(非常需要帮助) 这是我目前拥有的代码。我不知道从哪里开始ES5->ESNEXT转换 编辑:我忘了说我正试图避免使用ACF来做这件事 // Importing code libraries for this block import { __ } from '@wordpress/i18n'; import
// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText, MediaUpload, InspectorControls } from '@wordpress/block-editor';
import { Button, ColorPicker, ColorPalette, Panel, PanelBody, PanelRow } from '@wordpress/components';
registerBlockType('ccm-block/banner-block', {
title: __('Banner Block'),
icon: 'format-image', // from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: 'layout', // E.g. common, formatting, layout widgets, embed.
keywords: [
__('Banner Block'),
__('CCM Blocks'),
],
attributes: {
mediaID: {
type: 'number'
},
mediaURL: {
type: 'string'
},
title: {
type: 'array',
source: 'children',
selector: 'h1'
},
content: {
type: 'array',
source: 'children',
selector: 'p'
},
bannerButtons: {
type: 'array',
source: 'children',
selector: '.banner-buttons',
},
items: {
type: 'array',
default: []
}
},
/**
* The edit function relates to the structure of the block when viewed in the editor.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Component.
*/
edit: (props) => {
const {
attributes: { mediaID, mediaURL, title, content, bannerButtons },
setAttributes, className
} = props;
const onSelectImage = (media) => {
setAttributes({
mediaURL: media.url,
mediaID: media.id,
});
};
const onChangeTitle = (value) => {
setAttributes({ title: value });
};
const onChangeContent = (value) => {
setAttributes({ content: value });
};
const onChangeBannerButtons = (value) => {
setAttributes({ bannerButtons: value });
};
// console.log(items);
// var itemList = items.sort
return (
<div className={className}>
<div id="#home-banner">
<MediaUpload
onSelect={onSelectImage}
allowedTypes="image"
value={mediaID}
render={({ open }) => (
<Button className={mediaID ? 'image-button' : 'button button-large'} onClick={open}>
{!mediaID ? __('Upload Image', 'ccm-blocks') : <img src={mediaURL} alt={__('Featured Image', 'ccm-blocks')} />}
</Button>
)}
/>
<RichText
tagName="h1"
placeholder={__('Insert Title Here', 'ccm-blocks')}
className={className}
onChange={onChangeTitle}
value={title}
/>
<RichText
tagName="p"
placeholder={__('Insert your short description here...', 'ccm-blocks')}
className={className}
onChange={onChangeContent}
value={content}
/>
<RichText
tagName="ul"
multiline="li"
className="banner-buttons"
placeholder={ __('Add a banner button link (max of 2)', 'ccm-blocks') }
onChange={ onChangeBannerButtons }
value={ bannerButtons }
/>
</div>
</div>
);
},
/**
* The save function determines how the different attributes should be combined into the final markup.
* Which is then serialised into the post_content.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Frontend HTML.
*/
save: (props) => {
return (
<div className={ props.className }>
<div id="home-banner" style={{backgroundImage: `url(${ props.attributes.mediaURL })`}}>
<div class="container">
<div class="row">
<div class="col-12">
<div class="content-inner">
<RichText.Content tagName="h1" className={ props.className } value={ props.attributes.title } />
<RichText.Content tagName="p" className={ props.className } value={ props.attributes.content } />
<RichText.Content tagName="ul" className="banner-buttons" value={ props.attributes.bannerButtons } />
</div>
</div>
</div>
</div>
</div>
</div>
);
},
});
//导入此块的代码库
从'@wordpress/i18n'导入{{uu};
从'@wordpress/blocks'导入{registerBlockType};
从“@wordpress/block editor”导入{RichText、MediaUpload、InspectorControl};
从“@wordpress/components”导入{按钮、颜色选择器、颜色调色板、面板、面板主体、面板行};
registerBlockType('ccm-block/banner block'{
标题:u uu(‘横幅块’),
图标:'格式化图像',//来自Dashicons→ https://developer.wordpress.org/resource/dashicons/.
类别:'布局',//例如,通用、格式化、布局小部件、嵌入。
关键词:[
__(‘横幅块’),
__(‘CCM块’),
],
属性:{
mediaID:{
键入:“数字”
},
mediaURL:{
键入:“字符串”
},
标题:{
键入:“数组”,
资料来源:“儿童”,
选择器:“h1”
},
内容:{
键入:“数组”,
资料来源:“儿童”,
选择器:“p”
},
横幅按钮:{
键入:“数组”,
资料来源:“儿童”,
选择器:'.banner按钮',
},
项目:{
键入:“数组”,
默认值:[]
}
},
/**
*在编辑器中查看时,编辑功能与块的结构相关。
*
*@linkhttps://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
*@param{Object}props。
*@returns{Mixed}JSX组件。
*/
编辑:(道具)=>{
常数{
属性:{mediaID、mediaURL、标题、内容、横幅按钮},
setAttributes,类名称
}=道具;
const onSelectImage=(媒体)=>{
集合属性({
mediaURL:media.url,
mediaID:media.id,
});
};
const onChangeTitle=(值)=>{
setAttributes({title:value});
};
const onChangeContent=(值)=>{
setAttributes({content:value});
};
const onChangeBannerButtons=(值)=>{
setAttributes({bannerButtons:value});
};
//控制台日志(项目);
//var itemList=items.sort
返回(
(
{!mediaID?{('上传图像','ccm块'):}
)}
/>
);
},
/**
*save函数确定如何将不同的属性组合到最终标记中。
*然后将其序列化到post_内容中。
*
*@linkhttps://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
*@param{Object}props。
*@returns{Mixed}JSX前端HTML。
*/
保存:(道具)=>{
返回(
);
},
});
编辑2:这是我对它失败的看法
// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText, MediaUpload, InspectorControls } from '@wordpress/block-editor';
import { Button, ColorPicker, ColorPalette, Panel, PanelBody, PanelRow } from '@wordpress/components';
/**
* Register the Block
*
* @link https://wordpress.org/gutenberg/handbook/block-api/
* @param {string} name name.
* @param {Object} settings settings.
* @return {?WPBlock} The block, otherwise `undefined`.
*/
registerBlockType('ccm-block/banner-block', {
title: __('Banner Block'),
icon: 'format-image', // from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: 'layout', // E.g. common, formatting, layout widgets, embed.
keywords: [
__('Banner Block'),
__('CCM Blocks'),
],
attributes: {
mediaID: {
type: 'number'
},
mediaURL: {
type: 'string'
},
title: {
type: 'array',
source: 'children',
selector: 'h1'
},
content: {
type: 'array',
source: 'children',
selector: 'p'
},
bannerButtons: {
type: 'array',
source: 'children',
selector: '.banner-buttons',
},
items: {
source: 'query',
default: [],
selector: '.item',
query: {
title: {
type: 'string',
source: 'text',
selector: '.title'
},
index: {
type: 'number',
source: 'attribute',
attribute: 'data-index'
}
}
}
},
/**
* The edit function relates to the structure of the block when viewed in the editor.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Component.
*/
edit: (props) => {
const {
attributes: { mediaID, mediaURL, title, content, bannerButtons, items },
setAttributes, className
} = props;
const onSelectImage = (media) => {
setAttributes({
mediaURL: media.url,
mediaID: media.id,
});
};
const onChangeTitle = (value) => {
setAttributes({ title: value });
};
const onChangeContent = (value) => {
setAttributes({ content: value });
};
const onChangeBannerButtons = (value) => {
setAttributes({ bannerButtons: value });
};
// Clone an array of objects
function _cloneArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
// return repeater items
var itemList = items.sort(function(a, b){
return a.index - b.index;
}).map(function(item){
console.log(item);
return(
<RichText
tagName="h1"
placeholder={ __('Test', 'ccm-blocks') }
value={ item.title }
onChange={ function(value){
var newObject = Object.assign({}, item, {
title: value
});
setAttributes({
items: [].concat(_cloneArray(items.filter(function(itemFilter){
return itemFilter.index != item.index;
})), [newObject])
});
} }
/>
);
});
//
console.log(itemList);
return (
<div className={className}>
<div id="#home-banner">
<RichText
className="item-list"
tagName="h1"
value={ itemList }
/>
<Button
className="button add-row"
onClick={ function(){
setAttributes({
items: [].concat(_cloneArray(items), [{
index: items.length,
title: ""
}])
});
} }
>
Add a button
</Button>
<MediaUpload
onSelect={onSelectImage}
allowedTypes="image"
value={mediaID}
render={({ open }) => (
<Button className={mediaID ? 'image-button' : 'button button-large'} onClick={open}>
{!mediaID ? __('Upload Image', 'ccm-blocks') : <img src={mediaURL} alt={__('Featured Image', 'ccm-blocks')} />}
</Button>
)}
/>
<RichText
tagName="h1"
placeholder={__('Insert Title Here', 'ccm-blocks')}
className={className}
onChange={onChangeTitle}
value={title}
/>
<RichText
tagName="p"
placeholder={__('Insert your short description here...', 'ccm-blocks')}
className={className}
onChange={onChangeContent}
value={content}
/>
<RichText
tagName="ul"
multiline="li"
className="banner-buttons"
placeholder={ __('Add a banner button link (max of 2)', 'ccm-blocks') }
onChange={ onChangeBannerButtons }
value={ bannerButtons }
/>
</div>
</div>
);
},
/**
* The save function determines how the different attributes should be combined into the final markup.
* Which is then serialised into the post_content.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* @param {Object} props Props.
* @returns {Mixed} JSX Frontend HTML.
*/
save: (props) => {
return (
<div className={ props.className }>
<div id="home-banner" style={{backgroundImage: `url(${ props.attributes.mediaURL })`}}>
<div class="container">
<div class="row">
<div class="col-12">
<div class="content-inner">
<RichText.Content tagName="h1" className={ props.className } value={ props.attributes.title } />
<RichText.Content tagName="p" className={ props.className } value={ props.attributes.content } />
<RichText.Content tagName="ul" className="banner-buttons" value={ props.attributes.bannerButtons } />
</div>
</div>
</div>
</div>
</div>
</div>
);
},
});
//导入此块的代码库
从'@wordpress/i18n'导入{{uu};
从'@wordpress/blocks'导入{registerBlockType};
从“@wordpress/block editor”导入{RichText、MediaUpload、InspectorControl};
从“@wordpress/components”导入{按钮、颜色选择器、颜色调色板、面板、面板主体、面板行};
/**
*注册块
*
*@linkhttps://wordpress.org/gutenberg/handbook/block-api/
*@param{string}名称。
*@param{Object}设置。
*@return{?WPBlock}该块,否则为“未定义”。
*/
registerBlockType('ccm-block/banner block'{
标题:u uu(‘横幅块’),
图标:'格式化图像',//来自Dashicons→ https://developer.wordpress.org/resource/dashicons/.
类别:'布局',//例如,通用、格式化、布局小部件、嵌入。
关键词:[
__(‘横幅块’),
__(‘CCM块’),
],
属性:{
mediaID:{
键入:“数字”
},
mediaURL:{
键入:“字符串”
},
标题:{
键入:“数组”,
资料来源:“儿童”,
选择器:“h1”
},
内容:{
键入:“数组”,
资料来源:“儿童”,
选择器:“p”
},
横幅按钮:{
键入:“数组”,
资料来源:“儿童”,
选择器:'.banner按钮',
},
项目:{
来源:“查询”,
默认值:[],
选择器:'.item',
查询:{
标题:{
键入:“字符串”,
资料来源:“文本”,
选择器:'.title'
},
索引:{
键入:“编号”,
来源:'属性',
属性:“数据索引”
}
}
}
},
/**
*编辑功能与集团的结构相关
// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';
// Register the block
registerBlockType( 'test-block/custom-repeater-block', {
title: __('Repeater Block'),
icon: 'layout',
category: 'layout',
keywords: [
__('Custom Block'),
],
attributes: {
info: {
type: 'array',
selector: '.info-wrap'
}
},
// edit function
edit: (props) => {
const {
attributes: { info = [] },
setAttributes, className
} = props;
const infoList = (value) => {
return(
value.sort((a, b) => a.index - b.index).map(infoItem => {
return(
<div className="info-item">
<Button
className="remove-item"
onClick={ () => {
const newInfo = info.filter(item => item.index != infoItem.index).map(i => {
if(i.index > infoItem.index){
i.index -= 1;
}
return i;
} );
setAttributes({ info: newInfo });
} }
>×</Button>
<h3>Number {infoItem.index}</h3>
<RichText
tagName="h4"
className="info-item-title"
placeholder="Enter the title here"
value={infoItem.title}
style={{ height: 58 }}
onChange={ title => {
const newObject = Object.assign({}, infoItem, {
title: title
});
setAttributes({
info: [...info.filter(
item => item.index != infoItem.index
), newObject]
});
} }
/>
<RichText
tagName="p"
className="info-item-description"
placeholder="Enter description"
value={infoItem.description}
style={{ height: 58 }}
onChange={ description => {
const newObject = Object.assign({}, infoItem, {
description: description
});
setAttributes({
info: [...info.filter(
item => item.index != infoItem.index
), newObject]
});
} }
/>
</div>
)
})
)
}
return(
<div className={className}>
<div className="info-wrap">{infoList(info)}</div>
<Button onClick={title => {
setAttributes({
info: [...info, {
index: info.length,
title: "",
description: ""
}]
});
}}>Add Item</Button>
</div>
);
},
// save function
save: (props) => {
const info = props.attributes.info;
const displayInfoList = (value) => {
return(
value.map( infoItem => {
return(
<div className="info-item">
<RichText.Content
tagName="h4"
className="info-item-title"
value={infoItem.title}
style={{ height: 58 }}
/>
</div>
)
} )
)
}
return(
<div className={props.className}>
<div className="info-wrap">{ displayInfoList(info) }</div>
</div>
);
}
} )
attributes: {
services: {
type: "array",
source: "query",
default: [],
selector: "section .card-block",
query: {
index: {
type: "number",
source: "attribute",
attribute: "data-index",
},
headline: {
type: "string",
selector: "h3",
source: "text",
},
description: {
type: "string",
selector: ".card-content",
source: "text",
},
},
},
},
import produce from "immer";
import { __ } from "@wordpress/i18n";
import "./editor.scss";
import { RichText, PlainText } from "@wordpress/block-editor";
// import { useState } from "@wordpress/element";
export default function Edit({ attributes, setAttributes, className }) {
const services = attributes.services;
const onChangeContent = (content, index, type) => {
const newContent = produce(services, (draftState) => {
draftState.forEach((section) => {
if (section.index === index) {
section[type] = content;
}
});
});
setAttributes({ services: newContent });
};
return (
<>
{services.map((service) => (
<>
<RichText
tagName="h3"
className={className}
value={service.headline}
onChange={(content) =>
onChangeContent(content, service.index, "headline")
}
/>
<PlainText
className={className}
value={service.description}
onChange={(content) =>
onChangeContent(content, service.index, "description")
}
/>
</>
))}
<input
className="button button-secondary"
type="button"
value={__("Add Service", "am2-gutenberg")}
onClick={() =>
setAttributes({
services: [
...attributes.services,
{ headline: "", description: "", index: services.length },
],
})
}
/>
</>
);
}
export default function save({ attributes, className }) {
const { services } = attributes;
return (
<section className={className}>
{services.length > 0 &&
services.map((service) => {
return (
<div className="card-block" data-index={service.index}>
<h3>{service.headline}</h3>
<div className="card-content">{service.description}</div>
</div>
);
})}
</section>
);
}