Custom Blocks

Barebones supports custom WordPress blocks using block.json, ACF fields, PHP render templates, and block-specific assets. Block setup lives primarily in includes/blocks.php.

Block category

Barebones adds a custom block category called Custom Blocks. You can define your own categories in order to organise blocks by purpose or type. You can define a category within each block's block.json.

PHP
add_filter( 'block_categories_all', function ( $categories ) {
    $categories[] = [
        'slug'  => 'custom-blocks',
        'title' => 'Custom Blocks'
    ];

    return $categories;
});
JSON
"category": "custom-blocks"

Block directory

Each block lives in its own directory inside blocks/.

MD
blocks/split-content/
├── block.json
├── split-content.php
├── split-content.scss
├── split-content.js
└── preview.jpg

Use the same kebab-case name for the directory, PHP file, Sass file, JavaScript file, and compiled assets.

Block registration

Barebones automatically registers blocks by scanning for block.json files. A new block does not need to be manually registered if it follows the expected structure.

PHP
function bb_register_blocks() {
    $blocks = glob( get_stylesheet_directory() . '/blocks/*/block.json' );

    if ( $blocks ) {
        foreach ( $blocks as $block ) {
            register_block_type( $block );
        }
    }
}

add_action( 'init', 'bb_register_blocks' );

Block namespace

Custom blocks should use the custom-blocks/ namespace. This namespace is used by the editor restriction logic to hide any default WordPress blocks when creating a project that exclusively uses custom blocks.

JSON
"name": "custom-blocks/split-content"
PHP
/**
 * Restrict the block editor to custom blocks
 *
 * @return void
 */

add_filter('allowed_block_types_all', function ($allowed_blocks, $editor_context) {
    // Check if we're in the post editor
    if (!empty($editor_context->post)) {
        // Get all ACF blocks
        $acf_blocks = WP_Block_Type_Registry::get_instance()->get_all_registered();
        $acf_block_names = [];

        foreach ($acf_blocks as $block_name => $block) {
            if (strpos($block_name, 'custom-blocks/') === 0) {
                $acf_block_names[] = $block_name;
            }
        }

        return $acf_block_names;
    }

    return $allowed_blocks;
}, 10, 2);

ACF render templates

Blocks use ACF to connect block.json to a PHP render template. The render template lives inside the block directory. It can use normal ACF functions.

JSON
"acf": {
    "mode": "preview",
    "renderTemplate": "split-content.php"
}
PHP
$content   = get_field( 'content' );
$image     = get_field( 'image' );
$alignment = get_field( 'content_alignment' );

Block assets

Block styles and scripts are referenced from block.json.

JSON
"style": ["file:../../css/blocks/split-content.css"],
"viewScript": ["file:../../js/blocks/split-content.js"]

The source files live beside the block.

  • blocks/split-content/split-content.scss
  • blocks/split-content/split-content.js

Vite compiles these into the paths referenced by block.json.

Asset versioning

Block assets are versioned with the same file-based approach as global assets.

Barebones filters theme style and script URLs and adds the file modification time as the version.

PHP
add_filter( 'style_loader_src', 'bb_block_asset_versioning', 10, 2 );
add_filter( 'script_loader_src', 'bb_block_asset_versioning', 10, 2 );

Inline styles

Barebones prevents WordPress from inlining block styles. This encourages WordPress to load the compiled CSS files instead.

PHP
add_filter( 'styles_inline_size_limit', '__return_zero' );

Preview images

Blocks can define a static preview image in block.json.

JSON
"example": {
    "attributes": {
        "data": {
            "preview": "blocks/split-content/preview.jpg"
        }
    }
}

Each block then renders the preview image using bb_block_preview_image_src() when it detects that the block is being loaded in the 'Add Block' editor preview.

PHP
<?php if (bb_is_block_preview($block)): ?>

    <div class="block-preview"><img src="<?php echo bb_block_preview_image_src($block); ?>" /></div>

<?php else: ?>