2

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 ...
1
  • In gc-slider2/index.js, I removed the templateLock="all" from the InnerBlocks, and it is now displaying the plus sign for the gc-slider-items block. Which leaves me with a different problem of two add block plus signs.
    – Phil Huhn
    Commented Oct 1, 2023 at 22:53

1 Answer 1

0

In gc-slider2/index.js, I removed the templateLock="all" from the InnerBlocks, and it is now displaying the plus sign for the gc-slider-items block.

    <InnerBlocks
        template={SLIDER_TEMPLATE}
        allowedBlocks={ [ ] }
    />

Which leaves me with a different problem of two add block plus signs. See Gutenberg Innerblocks notallowedblocks on parent but allowedblock on child

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.