I'm converting a carousel/slider from a shortcode to a Gutenberg block. I got the first Gutenberg version working, but I want to convert that to use a InnerBlocks template, so the rich-text blocks can use the native toolbar (bold/italic/alignment/etc). So the base slider block now uses an InnerBlocks to render the template. I've added an additional block to render the items, which contains an InnerBlocks. The items block allows three blocks that each contain an InnerBlocks. The three blocks are slider item.
Slider (with Innerblocks template)
Slider Items (InnerBlocks with allows 3 different blocks)
Slider Item (3 different blocks each with an InnerBlocks)
The problem is the Slider Items does not seem to display the plus sign to add one of the 3 different Slider Item.
gc-slider2/block.json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "give-camp/gc-slider2",
"version": "0.1.0",
"title": "GC Slider 2",
"category": "text",
"icon": "slides",
"description": "Generic slider",
"attributes": {
"role": { "type": "string", "default": "" },
"ariaLabel": { "type": "string", "default": "Marketing data" },
"milliSec": { "type": "number", "default": 5000 },
"borderColor": { "type": "string", "default": "000000" },
"height": { "type": "string", "default": "460px" },
"width": { "type": "string", "default": "100%" },
"unit": { "type": "string", "default": "px" }
},
"supports": {
"type": "object",
"anchor": true,
"ariaLabel": true,
"color": {
"color": true,
"background": true,
"link": true,
"gradients": false
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"dimensions": {
"minHeight": true
},
"spacing": {
"margin": true,
"padding": true,
"__experimentalDefaultControls": {
"padding": true
}
},
"__experimentalBorder": {
"color": true,
"style": true,
"width": true,
"radius": true,
"__experimentalDefaultControls": {
"color": true,
"style": true,
"width": true,
"radius": true
}
}
},
"textdomain": "give-camp-blocks",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
gc-slider2/index.js
const { __ } = wp.i18n;
import {
registerBlockType
} from '@wordpress/blocks';
//
import metadata from './block.json';
import {
useBlockProps,
InspectorControls,
InnerBlocks
} from '@wordpress/block-editor';
//
import './style.scss';
//
function Slider2Edit(props) {
//
const {
attributes: { role, ariaLabel, milliSec, height, unit },
setAttributes,
textdomain,
clientId,
} = props;
const blockProps = useBlockProps({
className: 'gc-slider',
role: role,
"aria-label": { ariaLabel},
"data-millisec": { milliSec }
});
// Create a template of InnerBlocks with predefined attributes
const SLIDER_TEMPLATE = [
['core/heading', // header
{
placeholder: __("header title ..."),
level: 2,
className: 'gc-slider-header'
}
],
['give-camp/gc-slider-items', {} ],
['core/paragraph', // footer
{
placeholder: __("footer title ..."),
tagName: 'div',
className: 'gc-slider-footer',
}
]
];
//
return (
<div
{ ...blockProps }
>
<InnerBlocks
template={SLIDER_TEMPLATE}
templateLock="all"
/>
<div
className="gc-slider-counter has-text-align-center"
style={ { paddingTop: "3px", paddingBottom: "6px" } }
>1 of ?
</div>
</div>
);
//
}
//
function Slider2Save( props ) {
//
const {
attributes: { role, ariaLabel, milliSec, height },
textdomain,
} = props;
const blockProps = useBlockProps.save({
className: 'gc-slider',
role: role,
"aria-label": { ariaLabel},
"onMouseOver": "gc_slider_hover(this)",
"onMouseOut": "gc_slider_hover_leave(this)",
"data-millisec": { milliSec }
});
//
return (
<div
{ ...blockProps }
>
<InnerBlocks.Content />
<div
className="gc-slider-counter has-text-align-center"
style={ {paddingTop: "3px", paddingBottom: "10px" } }
>1 of ?
</div>
</div>
);
//
}
//
registerBlockType( metadata.name, {
apiVersion: metadata.apiVersion,
title: metadata.title,
supports: metadata.supports,
attributes: metadata.attributes,
//
edit: Slider2Edit,
save: Slider2Save,
} );
gc-slider-items/block.json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "give-camp/gc-slider-items",
"version": "0.1.0",
"title": "GC Slider Items",
"category": "text",
"icon": "align-pull-left",
"description": "Item wrapper for sliders' individual content",
"attributes": {
"allowedBlocks": { "type": "array", "default": [
"give-camp/gc-slider-item",
"give-camp/gc-slider-right-2-columns",
"give-camp/gc-slider-left-2-columns"] }
},
"supports": {
"anchor": true
},
"textdomain": "give-camp-blocks",
"editorScript": "file:./index.js",
"style": "file:./style-index.css"
}
gc-slider-items/index.js
const { __ } = wp.i18n;
import {
registerBlockType
} from '@wordpress/blocks';
//
import metadata from './block.json';
import {
useBlockProps,
InnerBlocks,
ButtonBlockAppender,
} from '@wordpress/block-editor';
//
import './style.scss';
// https://stackoverflow.com/questions/69637842/how-to-pass-attributes-to-child-gutenberg-blocks-in-innerblocks-template
function SliderItemsEdit(props) {
//
const {
attributes: { allowedBlocks },
usesContext
} = props;
const blockProps = useBlockProps({
className: 'gc-slider-items',
"aria-hidden": 'false',
"aria-roledescription": 'carousel'
});
//
return (
<div
{ ...blockProps }
>
<InnerBlocks
orientation="horizontal"
allowedBlocks={ allowedBlocks }
renderAppender={ () => <InnerBlocks.ButtonBlockAppender>
{ __('Add Item') }
</InnerBlocks.ButtonBlockAppender>
}
/>
</div>
);
//
}
//
function SliderItemsSave( props ) {
//
const {
} = props;
const blockProps = useBlockProps.save({
className: 'gc-slider-items',
"aria-hidden": 'false',
"aria-roledescription": 'carousel'
});
//
return (
<div
{ ...blockProps }
>
<InnerBlocks.Content
orientation="horizontal"
/>
</div>
);
//
}
//
registerBlockType( metadata.name, {
apiVersion: metadata.apiVersion,
title: metadata.title,
supports: metadata.supports,
attributes: metadata.attributes,
//
edit: SliderItemsEdit,
save: SliderItemsSave,
} );
`gc-slider-left-2-columns/block.json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "give-camp/gc-slider-left-2-columns",
"version": "1.0.0",
"title": "GC Slider Fade-in Left 2 Column Item",
"category": "text",
"icon": "align-pull-left",
"description": "Item wrapper for sliders' individual content",
"attributes": {
"style": {
"type": "object",
"default": {
"core/button" : {
"border" : {
"radius" : "8px"
}
}
}
}
},
"supports": {
"anchor": true
},
"textdomain": "give-camp-blocks",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:../gc-slider-utils/style-index.css"
}
`gc-slider-left-2-columns/index.js
const { __ } = wp.i18n;
import {
registerBlockType
} from '@wordpress/blocks';
import {
useBlockProps,
InnerBlocks
} from '@wordpress/block-editor';
import metadata from './block.json';
import '../gc-slider-utils/style-index.css';
import {
textGroupColumnTemplate,
imageColumnTemplate,
textImageAllowedBlocks,
} from '../gc-slider-utils/gc-slider-data';
//
function Slider2LeftColumnsEdit(props) {
//
const {
attributes: { fadeInDirection },
setAttributes
} = props;
const blockProps = useBlockProps( );
//
return (
<InnerBlocks
{ ...useBlockProps }
template={ [
[ 'core/columns', { className: ['gc-slider-item', 'wp-block-columns', 'is-layout-flex', 'wp-block-columns-is-layout-flex'],
style: { display: 'none' } },
[
[ 'core/column', { className: ['gc-fadeInLeft', 'gc-is-visible', 'gc-slider-2-column-image', 'wp-block-column', 'is-layout-flow', 'wp-block-column-is-layout-flow'],
style: { width: '50%' } },
imageColumnTemplate
],
[ 'core/column', { className: ['gc-fadeInLeftBig', 'gc-is-visible', 'gc-slider-2-column-title', 'wp-block-column', 'is-layout-flow', 'wp-block-column-is-layout-flow'],
style: { padding: '0px', width: '50%' } },
textGroupColumnTemplate
],
]
],
] }
allowedBlocks={ textImageAllowedBlocks }
/>
);
}
//
function Slider2LeftColumnsSave( props ) {
const {
attributes: { fadeInDirection },
} = props;
//
const _displayNone = {
display: "none",
};
const blockProps = useBlockProps.save({
className: 'gc-slider-item',
style: _displayNone
});
//
return (
<InnerBlocks.Content
{ ...useBlockProps }
/>
);
}
//
registerBlockType( metadata.name, {
apiVersion: metadata.apiVersion,
title: metadata.title,
supports: metadata.supports,
attributes: metadata.attributes,
//
edit: Slider2LeftColumnsEdit,
save: Slider2LeftColumnsSave,
} );
The gc-slider-right-2-columns is basically the same as the above except the image is on the right and the animation is the opposite.
gc-silder-utils/gc-slider-data.js
export const animationClasses = [
{ value: '', label: '- none -' },
{ value: 'gc-fadeIn', label: 'Fade In' },
{ value: 'gc-fadeInBig', label: 'Fade In Big' },
{ value: 'gc-fadeInLeft', label: 'Fade Left' },
{ value: 'gc-fadeInLeftBig', label: 'Fade Big Left' },
{ value: 'gc-fadeInRight', label: 'Fade Right' },
{ value: 'gc-fadeInRightBig', label: 'Fade Big Right' },
{ value: 'gc-fadeInUp', label: 'Fade Up' },
{ value: 'gc-fadeInUpBig', label: 'Fade Up Big' },
{ value: 'gc-fadeInDown', label: 'Fade Down' },
{ value: 'gc-fadeInDownBig', label: 'Fade Down Big' },
];
/**
** values for selection of animation dropdown
*/
export const onScrollShowClasses = [
{ value: 'gc-show-on-scroll', label: 'Show On-scroll' },
{ value: 'gc-show-once-on-scroll', label: 'Show Once On-scroll' }
];
/**
** Aria Values ... values for selection of type/role dropdown
*/
export const sliderRoles = [
{ value: 'img', label: 'Images' },
{ value: 'list', label: 'Content' }
];
/**
** gc slider right & left 2 columns text template
*/
export const textGroupColumnTemplate = [
[ 'core/group', { className: [ 'gc-slider-2-column-title-group', 'gc-slider-2-column-title-group-button-center' ] }, [
[ 'core/spacer', { height: '50px' } ],
[ 'core/heading', { level: 3, align: 'center', placeholder: 'Item Title ...' } ],
[ 'core/paragraph', { placeholder: 'Item description ...' } ],
[ 'core/button', { text: 'Action', align: 'center', style: { border: { radius: '8px' } } } ],
]
],
];
/**
** gc slider right & left 2 columns image template
*/
export const imageColumnTemplate = [
[ 'core/image', { } ],
];
/**
** gc slider right & left 2 columns allowed blocks
*/
export const textImageAllowedBlocks = [
'core/column',
'core/columns',
'core/heading',
'core/paragraph',
'core/group',
'core/spacer',
'core/image',
'core/button',
'core/buttons',
];
// End-of-file ...
gc-slider2/index.js
, I removed the templateLock="all" from the InnerBlocks, and it is now displaying the plus sign for thegc-slider-items
block. Which leaves me with a different problem of two add block plus signs.