Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Last active July 20, 2020 21:39
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save igorbenic/498f92f2d531ee0910370230605b3ae4 to your computer and use it in GitHub Desktop.
How to enable Inner Blocks in your Gutenberg Block | https://ibenic.com/enable-inner-blocks-gutenberg
<InnerBlocks allowedBlocks={ [ 'core/image', 'core/paragraph' ] } />
/**
* The edit function describes the structure of your block in the context of the editor.
* This represents what the editor will render when the block is used.
*
* The "edit" property must be a valid function.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*/
edit: function( props ) {
const { attributes, setAttributes } = props;
// Creates a <p class='wp-block-cgb-block-inner-blocks'></p>.
return [
<InspectorControls>
<PanelBody title={ __( 'Content Settings' ) }>
<SelectControl
label={ __('Hide this if user:') }
value={ attributes.paid }
options={ [ { label: __( 'Has a Paid Membership' ), value: 'true' }, { label: __( 'Does not have a Paid Membership' ), value: 'false' } ] }
onChange={ ( paid ) => { setAttributes( { paid } ); } }
/>
</PanelBody>
</InspectorControls>,
<div className={ props.className }>
{ __( 'Add Blocks that you can hide or show based on criteria' ) }
<InnerBlocks />
</div>
];
},
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by Gutenberg into post_content.
*
* The "save" property must be specified and must be a valid function.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*/
save: function( props ) {
return (
<InnerBlocks.Content />
);
},
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { InspectorControls, InnerBlocks } = wp.editor;
const { PanelBody, SelectControl } = wp.components;
/**
* Register: aa Gutenberg Block.
*
* Registers a new block provided a unique name and an object defining its
* behavior. Once registered, the block is made editor as an option to any
* editor interface where blocks are implemented.
*
* @link https://wordpress.org/gutenberg/handbook/block-api/
* @param {string} name Block name.
* @param {Object} settings Block settings.
* @return {?WPBlock} The block, if it has been successfully
* registered; otherwise `undefined`.
*/
registerBlockType( 'ibenic/inner-blocks', {
// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
title: __( 'Inner Blocks' ), // Block title.
icon: 'screenoptions', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: 'common', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
keywords: [
__( 'inner-blocks' ),
],
attributes: {
paid: {
type: 'string'
}
},
// edit and save methods are here...
}
const ALLOWED_BLOCKS = [ 'coblocks/accordion-item' ];
parent: [ 'coblocks/accordion' ]
registerBlockType( 'ibenic/child-block', {
title: 'This is a Child Blcok',
// Only allow in a registered parent-block:
parent: [ 'ibenic/parent-block' ],
...
});
<?php
add_action( 'init', 'inner_blocks_register_blocks' );
function inner_blocks_register_blocks() {
register_block_type( 'ibenic/inner-blocks', array(
'editor_script' => 'inner_blocks-cgb-block-js',
'editor_style' => 'inner_blocks-cgb-block-editor-css',
'render_callback' => 'inner_blocks_render_content',
) );
}
<?php
/**
* Render Inner Blocks.
*
* @param array $attributes
* @param string $content
*
* @return string
*/
function inner_blocks_render_content( $attributes, $content = '' ) {
if ( 'true' === $attributes['paid'] && inner_blocks_has_user_paid_membership() ) {
return $content;
} elseif ( 'false' === $attributes['paid'] && ! inner_blocks_has_user_paid_membership() ) {
return $content;
}
return '';
}
/**
* This is a dummy function that returns TRUE always.
*/
function inner_blocks_has_user_paid_membership() {
return true;
}
<InnerBlocks template={[
[ 'core/paragraph', { placeholder: 'Enter side content...' } ],
[ 'core/paragraph', { placeholder: 'Second Content' } ]
]}/>
@rameezwp
Copy link

Hi, its not working with latest gutenberg, any idea?

@emfluenceindia
Copy link

I have a requirement where I need to place InnerBlocks alongside a RichText component. Like this:

edit: function( props ) {
    var textContent = props.attributes.textContent;
    function onChangeTextContent( content ) {
	props.setAttributes( { textContent: content } );
    }

   return (
	<div className={ props.className }>
                <label class="editor-content-section-label">Content for gray section</label>
		<RichText
                    className={props.className}
                    onChange={onChangeTextContent}
                    value={textContent}
                    placeholder="Add content"
                />
                <InnerBlocks allowedBlocks={'hallmark/white-content-container'}/>
	</div>
   );
},
save: function( props ) {
   return null;
},

I am new in Gutenberg development. I have three questions.

  1. Is this the right way to do it? The requirement is white-content needs to go inside the container of RichText.
  2. How can I save the entire content using render_callback. The callback function saves the content of RichText fine but I don't know how to save the content of InnerBlock.

The final output should look like this:

<div class="gray-content">
   Content of RichText 
   <div class="white-content">
       Content of InnerBlock
   </div>
</div>
  1. Although I have restricted InnerBlocks to sow only one block (<InnerBlocks allowedBlocks={'hallmark/white-content-container'}/>), the inserter dialog is showing all available blocks, both core and custom ones.

Please let me know how I can do it!

@GilCarvalhoDev
Copy link

  1. Although I have restricted InnerBlocks to sow only one block (<InnerBlocks allowedBlocks={'hallmark/white-content-container'}/>), the inserter dialog is showing all available blocks, both core and custom ones.

Please let me know how I can do it!

I have the same problem. Did you manage to solve?

@markhowellsmead
Copy link

allowedBlocks needs to be an array. <InnerBlocks allowedBlocks={['hallmark/white-content-container']}/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment