Skip to content

Add class to register all blocks inside the project #17

@claytoncollie

Description

@claytoncollie

Is your enhancement related to a problem? Please describe.

In our themes and plugins, we have have a block registration function that look in a particular diectory and finds all of the block.json files. This code is repetative and should be abstracted into the framework. The example below is a rough guide but still needs tweaking to follow project standards.

Abstract class

<?php

namespace ProjectName;

use TenupFramework\Module;
use TenupFramework\ModuleInterface;

/**
 * Block registration
 */
abstract class BlockRegistrar implements ModuleInterface {
    
    use Module;

    /**
     * Get the blocks directory path
     */
    abstract protected function get_blocks_directory(): string;

    /**
     * Can this module be registered?
     */
    public function can_register(): bool {
        return true;
    }

    /**
     * Register hooks
     */
    public function register(): void {
        add_action( 'init', [ $this, 'register_blocks' ], 10, 0 );
    }

    /**
     * Automatically registers all blocks from the plugin's blocks directory
     */
    public function register_blocks(): void {
        $blocks_dir = $this->get_blocks_directory();
        if ( ! file_exists( $blocks_dir ) ) {
            return;
        }

        $block_json_files = glob( $blocks_dir . '*/block.json' );
        if ( empty( $block_json_files ) ) {
            return;
        }

        $block_names = [];

        foreach ( $block_json_files as $filename ) {
            $block_folder = dirname( $filename );
            
            $block = register_block_type_from_metadata( $block_folder, $args );
            if ( ! $block ) {
                continue;
            }

            $block_names[] = $block->name;
        }

        if ( ! empty( $block_names ) ) {
            $this->register_allowed_block_types( $block_names );
        }
    }


    /**
     * Register blocks in allowed_block_types_all filter
     */
    protected function register_allowed_block_types( array $block_names ): void {
        add_filter(
            'allowed_block_types_all',
            function ( array|bool $allowed_blocks ) use ( $block_names ): array|bool {
                if ( ! is_array( $allowed_blocks ) ) {
                    return $allowed_blocks;
                }
                return array_merge( $allowed_blocks, $block_names );
            }
        );
    }
}

And how the project would use this class

<?php

namespace ProjectName;

use TenupFramework\BlockRegistrar;

/**
 * Blocks
 */
class Blocks extends BlockRegistrar {

    /**
     * Get the blocks directory for this plugin
     */
    protected function get_blocks_directory(): string {
        return IPATH_TO_BLOCKS_DIST_DIR;
    }
}

Designs

No response

Describe alternatives you've considered

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions