Skip to content
Verdant Studio logo

How to get default attributes with parse_blocks

The parse_blocks WordPress function parses blocks out of a content string and while this does return changed block attributes it actually doesn’t return default attribute values defined in block.json. This means if an attribute is not set in the block’s content, parse_blocks() will not include it in the parsed block attributes.

So if you take the block.json example below:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "verdant-studio/my-block",
	"title": "My Block",
	...
	"attributes": {
		"animation": {
			"type": "string",
			"default": "falling-stars"
		},
	},
    ...
}

The parse_blocks() function won’t return the default attributes for “animation” unless you’ve chosen to change them to something else.

Getting the default attributes in a dynamic block

To ensure that the parsed block includes default values from block.json, we’ll need to manually merge the default values with the parsed attributes. Here is how we can do this:

1. Get the default values from a block.json

# Get a block's default attributes.
function get_block_default_attributes($block_name) {
    $block_registry = WP_Block_Type_Registry::get_instance();
    $block_type = $block_registry->get_registered($block_name);

    if ($block_type && isset($block_type->attributes)) {
        return array_map(function($attribute) {
            return isset($attribute['default']) ? $attribute['default'] : null;
        }, $block_type->attributes);
    }

    return [];
}

2. Parse the blocks and merge the default attributes

# Merge the content attributes with default attributes.
function parse_blocks_with_defaults($content) {
    $blocks = parse_blocks($content);

    foreach ($blocks as &$block) {
        if (isset($block['blockName'])) {
            $default_attributes = get_block_default_attributes($block['blockName']);
            $block['attrs'] = array_merge($default_attributes, $block['attrs'] ?? []);
        }
    }

    return $blocks;
}

3. Use the parsed blocks with merged default attributes

Now in our PHP code we can call the parse_blocks_with_defaults function to get an array of any block’s attributes including the defaults and those we’ve changed along the way.

$content = get_the_content();
$blocks = parse_blocks_with_defaults($content);

foreach ($blocks as $block) {
    # change the line below to your block's name
    if ($block['blockName'] === 'verdant-studio/my-block') { 
        $attrs = $block['attrs'];
        # at this point you can use $attrs :-)
    }
}

Complete code example

# Get a block's default attributes.
function get_block_default_attributes($block_name) {
    $block_registry = WP_Block_Type_Registry::get_instance();
    $block_type = $block_registry->get_registered($block_name);

    if ($block_type && isset($block_type->attributes)) {
        return array_map(function($attribute) {
            return isset($attribute['default'] ) ? $attribute['default'] : null;
        }, $block_type->attributes);
    }

    return [];
}

# Merge the content attributes with default attributes.
function parse_blocks_with_defaults($content) {
    $blocks = parse_blocks($content);

    foreach ($blocks as &$block) {
        if (isset($block['blockName'])) {
            $default_attributes = get_block_default_attributes($block['blockName']);
            $block['attrs'] = array_merge($default_attributes, $block['attrs'] ?? []);
        }
    }

    return $blocks;
}

# Usage:
$content = get_the_content();
$blocks = parse_blocks_with_defaults($content);

foreach ($blocks as $block) {
    # change the line below to your block's name
    if ($block['blockName'] === 'verdant-studio/my-block') { 
        $attrs = $block['attrs'];
        # at this point you can use $attrs :-)
    }
}

About Robert

Plugin developer and contributor