Gutenberg - Multiple InnerBlocks in one block-type

Seems like gutenberg Innerblocks can only be used once in a block

Note: A block can render at most a single InnerBlocks and InnerBlocks.Content element in edit and save respectively. To create distinct arrangements of nested blocks, create a separate block type which renders its own InnerBlocks and assign as the sole allowedBlocks type.

Source: https://github.com/WordPress/gutenberg/tree/master/packages/block-editor/src/components/inner-blocks

You need a create another custom block(for the column only) along with this block which also uses Innerblock inside it so that other blocks can be nested inside. You can make use of allowedBlocks to only allow your custom column in this block


If you meant to add multiple gutenberg blocks via InnerBlock from 'block-editor' as shown below, there is no way to add multiple blocks yet:

const BLOCK_TEMPLATE = [
  ['image-slider', { width: 800, height: 400 }],
  ['menu'],
];

registerBlockType('peregrine/inner-block-demo', {

  title: 'Inner Block Demo',

  edit({ className }) {
    return (
      <div className={className}>
        <InnerBlocks
          template={BLOCK_TEMPLATE}
          templateLock="all"
        />
      </div>
    );
  },

  save() {
    return (
      <div>
        <InnerBlocks.Content />
      </div>
    );
  },
});

Multiple inner blocks have complexities that don't seem worth the effort, and in general it either hints at a block that should be broken down into multiple simpler blocks, or with block attributes (not children). Let us know how the above suggestion work for you and we could revisit.

You can follow the discussion here: https://github.com/WordPress/gutenberg/issues/6808

But, your code looks more like adding inner elements and that is possible.

So to clarify further, what you supply to registerBlockType function is not block. A gutenberg block a graceful shortcode, something like this:

<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>
<!-- /wp:image -->

Or this:

<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->

First one is called static block because it has its content in it. Second one is called dynamic block because it is self closig block and has no content. Content will be retrived from the php callback you supplied when you register your block.

Gutenberg uses React to print visual representation of the block onto editor screen. edit method on settings object should return a react element, this element will be used to produce visual representation for the block in the editor. save method also should return react element, but this element will be rendered into static html and saved into database: <figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>. Now, dynamic blocks has no return element since they return null, so there is no content in them, that's is why they are self closing.

When server responds a request, it will get the content stored in the database and runs it through parser to see if it is static or dynamic block. If block is static, it has its content in itself so that content will be returned. If it is dynamic, registered callback function will be invoked and its return value will be returned.

Now, to answer your question, save and edit functions should return react element. A react element has to have single root element, but inner elements can any regular html like this one:

<div>
  <h1>Hello world</h1>
  <p>This is a sentence</p>
</div>

This is for performance reasons. DOM operations are expensive, that's is why it has single entry point into the DOM. That is why it is very fast. It has its own DOM then on, an whole tree resides in memory. React will walk through its DOM tree when a change takes place and render only changed branch, will not paint whole tree with every little change.

Important detail here is the code above looks like html but it is not, it is jsx. React can not render html directly. Jsx will be transpiled into react element by a transpiler like babel.

There is also createElement method on React which can be used to create react element. wp re-exports this method.

You can render one react element in another one. Without learning react you can never fully grasp the power or the potential of blocks. React library is not that large. Once you grasp the idea behind it you can learn it enough to be productive in a week or two.