Carbon-fields: Can we create a nestable block?

Created on 17 Jan 2019  路  20Comments  路  Source: htmlburger/carbon-fields

I'm assuming the answer is no, but I'm curious if we can create a block with Carbon Fields that will allow other blocks to be nested inside. Basically a container type block.

[type] question

Most helpful comment

@speedwheel,

At the moment this is not feasible because Gutenberg takes full control over the rendering of the blocks and doesn't expose any useful hooks that we can use to implement this behavior.

I'm going to close this issue since the nested blocks are included in our latest release - v3.1.0-beta.1.

Feel free to add your comments below if you want to continue our discussion.

All 20 comments

Hi @JiveDig,

This feature isn't currently supported by Carbon Fields but it's definitely an interesting idea.

We discussed the potential uses internally and we're concerned that it may shift the purpose of the library from create-a-bunch-of-custom-fields into build-your-layout-container-structure territory. We'd be fine if people use Carbon Fields for that, but it seems to be a problem that's being tackled by Gutenberg itself(and blocks plugins like CoBlocks).

Building layouts in this manner will result in a more rigid markup structure, which is not necessarily a bad thing -- less freedom for the user(in certain blocks) means less opportunities for them to screw up a carefully crafted design.

We'll keep the issue open so it can gather additional feedback from the community. We'll consider adding it in 3.1

In the meantime - could you please share the concrete use case that you had before opening the issue? It'd be good for us to have a little more context.

Hi there, thanks for chiming in :)

I'm trying to build a dynamic, container type block for exactly those reasons. At this point, our theme has a template that uses a CMB2 repeater to create "sections". Each row has a WYSIWYG and a bunch of layout related settings (Height, width, background color/image, etc). It works great, but now we wanna use Gutenberg/block editor for obvious reasons.

Currently, our theme has a small, utility-class based CSS framework built in (similar to the flexbox stuff in Tailwind/Bootstrap). This allows us to create columns/rows via the markup without any extra CSS.

My goal is to be able to build a dynamic Section/Container block that uses our HTML structure. IMO it would be relatively simple. Since the block will be dynamic, all I need to do is call my helper function to get_section( $attributes, $content ) on render, and save would just return return <InnerBlocks.Content />; This way I have full control over the markup and can change it moving forward with no issues, and if they change themes, the inner blocks would still be there.

Maybe I just need to dive into building blocks myself, but the use-case currently fits the purpose of libraries like Carbon/CMB2/ACF/Metabox/etc. Many people use them just for settings that control layout/design aspects, and this would be no different.

I know they are looking to add a similar block to core in phase 2 (whenever that is) https://github.com/WordPress/gutenberg/issues/4900 but this will not be a dynamic block and won't have the settings/attributes that we have, nor the markup we use. Point being, it won't be as tightly integrated in our theme as we need or we'd like.

I don't know if CF allows you to use fields as sidebar settings (attributes?) in the block editor at all, or if they only register fields in the block container itself. This may be the most difficult part of allowing this in CF. If that's already possibly, then it seems like a lot less work to have a parameter/flag to make it a dynamic block and allow innerblocks.

FWIW, our theme also has some other custom field related settings/options so we need a library anyway. It seemed like a natural move to CF if I could handle some of our core blocks inside CF as well as migrate our custom fields/metaboxes/settings.

Hope this helps. Let me know if you need more details. Thanks so much :)

Thanks, @JiveDig! We'll be experimenting with this feature in the comings weeks and see if it's a viable approach to build blocks.

Will update the ticket once we have progress

Thanks! As an aside, can CF be used to create attributes/settings in the Gutenberg sidebar? Or only in the block itself?

Another user opened this issue yesterday -- https://github.com/htmlburger/carbon-fields/issues/649

@emohamed I also am interested about nestable blocks, this option would open many doors in terms of managing content for your website.

@speedwheel @JiveDig

We built a first preview for this feature -- you can check it out here: https://github.com/htmlburger/carbon-fields/tree/feature/nested-blocks

Here are the docs(still work in progress): https://github.com/htmlburger/carbon-fields-docs/blob/feature/docsify/containers/gutenberg-blocks.md

Block::make( __( 'My Shiny Gutenberg Block' ) )
    ->add_fields( array(
        // ...
    ) )
    ->set_inner_blocks( true )
    ->set_render_callback( function ($field, $atts, $inner_blocks_content) {
        echo $inner_blocks_content;
    } );

You can use ->set_inner_blocks_position( 'below' | 'above' ) to place the inner blocks in the respective position in the editor.

Also, you can pass a template when setting up inner blocks like this:

Block::make( __( 'My Shiny Gutenberg Block' ) )
    ->add_fields( array(
        // ...
    ) )
    ->set_inner_blocks( true )
    ->set_inner_blocks_template( array(
        array( 'core/heading' ),
        array( 'core/paragraph' )
    ) )
    ->set_render_callback( function ($fields, $atts, $inner_blocks_content) {
        echo $inner_blocks_content;
    } );

Wow cool! I'll play with it as soon as I can.
Confirming this is only for nested blocks, not creating attributes/settings in the Gutenberg sidebar? From quick glance that seems to be the case. Still very cool.

@JiveDig confirmed, this is just allowing nested blocks.

Note - it's rough around the edges, so don't use it for important stuff just yet.

@emohamed thank you, this is awesome.

@emohamed can we define where we want to render the inner blocks inside the parent?

@speedwheel

You can specify the position with set_inner_blocks_position method. The available options are above and below.

@vvasilev- Thanks, I want a more custom position inside the main parent.

<div><div><div>{{inner blocks}}</div></div></div>

@speedwheel,

Can you provide us with example code, so we can better understand what you're trying to achieve?

On a side note, the render callback accepts the HTML of inner blocks as the third parameter so you can output the string anywhere that you want.

@vvasilev- Thanks, now I saw the 3rd parameter, actually that works for what I want to do.

But as a bonus, I think it would be helpul if you would have the name of the block as the key of the array and the value the content of the inner block:

Array
(
    [0] => Array (
        ['content'] = > 'this is the content of the inner block'
        ['block_name'] => 'wp:carbon-fields/test-block'
    )
    [1] => Array (
        ['content'] = > 'this is the content of the inner block 2'
        ['block_name'] => 'wp:carbon-fields/test-block'
    )
    [2] => Array (
        ['content'] = > 'this is the content of the inner block 3'
        ['block_name'] => 'wp:carbon-fields/test-block2'
    )
)

--- or ---

Array
(
    [0] => Array (
        ['content'] = > Array() //inner block custom fields values
        ['block_name'] => 'wp:carbon-fields/test-block'
    )
    [1] => Array (
        ['content'] = > Array() //block custom fields values
        ['block_name'] => 'wp:carbon-fields/test-block'
    )
    [2] => Array (
        ['content'] = > Array() //inner block custom fields values
        ['block_name'] => 'wp:carbon-fields/test-block2'
    )
)

This would give you more flexibility where to render each block depending of the block type.

@speedwheel,

At the moment this is not feasible because Gutenberg takes full control over the rendering of the blocks and doesn't expose any useful hooks that we can use to implement this behavior.

I'm going to close this issue since the nested blocks are included in our latest release - v3.1.0-beta.1.

Feel free to add your comments below if you want to continue our discussion.

Finally got to play with this. It's a great start! I hit some issues though, most importantly that I can't edit the inner blocks after saving. Either in preview or edit mode, the paragraph block I added as an inner block is stuck. I can't edit it.

I can't see any docmentation about

->set_inner_blocks( true )

in the documentation or the link to the readme file above: https://github.com/htmlburger/carbon-fields-docs/blob/feature/docsify/containers/gutenberg-blocks.md

Has any further work been done on this? Does nestable carbon blocks work and allow nested blocks to be edited too?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

leurdo picture leurdo  路  3Comments

dmhendricks picture dmhendricks  路  3Comments

halvardos picture halvardos  路  3Comments

bjoernhasse picture bjoernhasse  路  3Comments

ArekZw picture ArekZw  路  4Comments