Search code examples
wordpress-gutenbergwordpress-plugin-creation

Gutenberg Block Supports: How to set a default background color?


When I add Block Supports for backgroundColor to my custom, dynamic WordPress/Gutenberg block, I would like for the picker to already have a default color selected. I followed the directions from Reference Guide, but something is missing.

My block.json

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "my-custom-block",
    "version": "0.1.0",
    "title": "My Block Title",
    "category": "widgets",
    "description": "My Block Description",
    "supports": {
        "html": false,
        "color": {
            "background": true,
            "text": false,
            "link": false
        }
    },
    "textdomain": "my-custom-block",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css",
    "attributes": {
        "style": {
            "type": "object",
            "default": {
                "color": {
                    "background": "#b50000"
                }
            }
        },
        "backgroundColor": {
            "type": "string",
            "default": "" // The WP Reference Guide says this will be a preset slug. Adding one does not help me.
        }
    }
}

My block.php

function my_block_init() {
    
    register_block_type('my_custom_block', [
        'render_callback' => 'markup_my_custom_block',
        'attributes' => [
            'backgroundColor' => [
                'type' => 'string',
                'default' => '#b50000'
            ]
        ]
    ] );
}
add_action( 'init', 'my_block_init' );

My render function (basic at this point)

function markup_my_custom_block($attr, $content) {
    return $content;
}

My edit.js

import { __ } from '@wordpress/i18n';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

/**
 * @return {WPElement} Element to render.
 */

export default function Edit({ attributes, setAttributes }) {

    return (
        <div { ...useBlockProps() }>
            <InnerBlocks />

        </div>
    );
}

My save.js

import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';

/**
 * @return {WPElement} Element to render.
 */
export default function save() {
    return (
        <div { ...useBlockProps.save() }>
            <div>
                <InnerBlocks.Content />
            </div>
        </div>
    )
}

This part works: The Block Supports background color picker appears as expected and I can set the background color for my block as expected. The block renders with the selected color on the front end.

Here is where I am stuck: when the user adds my block, I would like for the picker to already have a default color selected (Instead of showing the circle slash). Since this is a plugin, I would like it to be based on hex rather than a theme color.

I found a couple of tutorials (including this one) that say to add the default style to the block.json, but the editor seems to be ignoring it.

I am not getting any JS or PHP errors.

Note: I know that my example here is very simple, but I really do want to use a dynamic block with a render_callback function because I am going to add some custom stuff once I learn how to use Block Supports.

------ Update and Solution ------

This seems to be a problem with dynamic blocks.

@S.Walsh is correct that the the block.json attributes for default: color make the color picker select a color by default.

As soon as I add 'attributes' (any attributes) to my register_block_type, however, the default color in the editor is ignored. I was able to fix this by adding 'style' as an attribute object to my block.php register_block_type.

The solution is to keep the block.json the way it is and modify the block.php like this:

function my_block_init() {
    
    register_block_type('my_custom_block', [
        'render_callback' => 'markup_my_custom_block',
        'attributes' => [
            'style'  => [
                'type'  => 'object',
                'default'  => [
                    'color'  =>
                    [
                        'background'  => '#b50000'
                    ]
                ]
            ]
        ]
    ] );
}
add_action( 'init', 'my_block_init' );

Solution

  • I've tested your code by creating a new block and adding your attributes to block.json with your edit/save functions. The background color works as expected for the parent block; though when you click inside your block (InnerBlocks > Paragraph) the background color for paragraph (or any InnerBlock added) won't be set as the Paragraph/InnerBlock has its own attributes that aren't inherited from your blocks block.json.

    Parent block - Background color set

    InnerBlock > Paragraph - No background color set

    Your block.json attributes for default:color:background produced this markup (note: the has-background and background-color is added as expected):

    <!-- wp:create-block/so-75596656 -->
    <div class="wp-block-create-block-so-75596656 has-background" style="background-color:#b50000"><div><!-- wp:paragraph -->
    <p></p>
    <!-- /wp:paragraph --></div></div>
    <!-- /wp:create-block/so-75596656 -->
    

    If you are not seeing the background default change, run the build process again, remove the block from the page completely then clear the cache before testing readding the block again.