I also had this problem, and what I did is to define the attribute inside PHP and use wp_localize_script
to pass down the array.
Then you can pass in the variable in render_callback
using use ($var)
For example:
$js = get_stylesheet_directory_uri() . '/assets/js';
$css= get_stylesheet_directory_uri() . '/assets/css';
$default_attributes = [
'alignment' => [ 'type' => 'string', 'default' => 'left' ],
'iconPosition' => [ 'type' => 'string', 'default' => 'left' ],
'textColor' => [ 'type' => 'string', 'default' => 'var(--text)' ],
'bgColor' => [ 'type' => 'string', 'default' => 'var(--textInvert)' ],
];
wp_register_script( 'my-block', $dist . '/my-block.js', [ 'wp-blocks', 'wp-dom' ] , null, true );
wp_register_style( 'my-block', $dist . '/my-block.css', [ 'wp-edit-blocks' ] );
wp_localize_script( 'my-block', 'myBlockLocalize', [ 'attributes' => $default_attributes ] );
register_block_type( 'my/block', [
'editor_style' => 'my-block',
'editor_script' => 'my-block',
'render_callback' => function( $atts, $inner_blocks = null ) use ( $default_attributes ) {
$default_values = array_map( function( $a ) {
return $a['default'] ?? '';
}, $default_attributes );
$atts = wp_parse_args( $atts, $default_values );
ob_start();
// output the HTML here, I believe you can use get_template_parts()
return ob_get_clean();
}
] );
In your JS:
...
registerBlockType( 'my/block', {
title: 'My Block',
icon: 'id',
category: 'layout',
example: {},
attributes: myBlockLocalize.attributes,
// ...
} );
...