Skip to content

Creating a New Block

Tom Rhodes edited this page Aug 16, 2024 · 10 revisions

Do you ACTUALLY Need a New Block?

Take a moment before creating a new block, do you actually need it? Could you create what's needed using core tools? Consider:

  • Patterns.
  • The Block Bindings API.
  • The Interactivity API.

This list is sure to grow. The gold standard for any block development, is simply not creating a new block. We reduce our maintenance burden and overall reliance on developed code if we make use of the tools that already exist.

Here's a fantastic article on how to extend existing blocks.

If you considered your options carefully, and you've chosen to create a new block for the monorepo, there's some steps and rules you'll need to follow.

Cloning the Monorepo Locally.

The monorepo is designed to be cloned into the /plugins/ folder of any WordPress Install for active development of new blocks. Use your preferred method of cloning to achieve this.

Activating the Autoloader.

Once you have cloned the repo to your wp-content/plugins/ folder, you'll see a new plugin WordPress.com Special Projects Blocks Monorepo Autoloader, activate this on your install. Your install will now autoload any blocks you're actively working on. "Actively working on" is determined by any block plugins in the monorepo that have a build folder present. We do not track this by default, so the assumption is you've built this block via npm run build and are ready for testing or development.

TL:DR

  1. Clone monorepo into /plugins/
  2. Activate the WordPress.com Special Projects Blocks Monorepo Autoloader plugin.
  3. Run npm i and npm run build in whatever block plugin folder you want to work on.
  4. That block plugin will be autoloaded in the background.

Scaffolding Your Block.

Use @wordpress/create-block to scaffold your block. If you cloned the entire monorepo locally, you would cd into the monorepo root, and then use npx @wordpress/create-block@latest plugin-slug --namespace wpcomsp to create your block scaffold.

Note: All block namespacing should be wpcomsp, please keep your blocks project agnostic, that means do not include project data, naming, or specific styling in your block.

Note: Add a CHANGELOG.md file to your block plugins root. This is Required for our build processes.

Development Notes.

  • composer i on the repo root to pull in our custom WPCS standards.
  • Each folder at the repo root is an individual block plugin. We have a build script that turns these into releases for users to install on a single plugin basis.
  • Ensure your plugin entry filename matches your plugin folder name. e.g plugin-slug/plugin-slug.php
  • Use 1 block plugin per block. The only exception to this is with block dependencies, e.g a tabs block that uses a container block, and then child blocks for content wrapping.
  • Use wpcomsp for all namespacing.
  • Add a CHANGELOG.md file to your block plugins root.
  • Keep your block project agnostic.
  • Blocks in this monorepo should represent wireframes in terms of styling. They should appear as non-broken in the latest twenty-XYZ theme, but otherwise all styling for the block should be kept to an absolute minimum in the block itself.
  • If you're adding styling options as controls to the block, this is acceptable (e.g text colour controls), but keep written styles to an absolute minimum. Structural only.
  • Style your blocks more thoroughly from within your main project. You can use block stylesheets to accomplish this in a granular, performant way.
  • Add PHP filters to your block generously, if it is PHP rendered. Think about the next developer who might use this block in their project.
  • Ensure your plugin description, and block description block.json is verbose and clear. We will re-use these in automated tooling.
  • Add a screenshot.png to the root of your block plugin. This should be 1200x800px (width by height) and show your block as it appears in your project. Try to make it clear the blocks purpose. This will be used in automated tooling.

Auto Updater.

This repo includes an auto-update class in the /.utilities/ folder. Copy this into your plugin inside a /classes/ folder at the plugin root. You should then add the following code to your plugins entry PHP file:

// If no other WPCOMSP Block Plugin added the self update class, add it.
if ( ! class_exists( 'WPCOMSP_Blocks_Self_Update' ) ) {
	require __DIR__ . '/classes/class-wpcomsp-blocks-self-update.php';

	$wpcomsp_blocks_self_update = WPCOMSP_Blocks_Self_Update::get_instance();
	$wpcomsp_blocks_self_update->hooks();
}

/**
 * Setup auto-updates for this plugin from our monorepo.
 * Done in an anonymous function for simplicity in making this a drop-in snippet.
 *
 * @param array $blocks Array of plugin files.
 *
 * @return array
 */
add_filter(
	'wpcomsp_installed_blocks',
	function ( $blocks ) {
		$plugin_data = get_plugin_data( __FILE__ );

		// Add the plugin slug here to enable autoupdates.
		$blocks[] = 'dynamic-table-of-contents';

		return $blocks;
	}
);

Be sure to replace 'dynamic-table-of-contents' with your own plugins slug. In doing this we create an auto-updater that works even if a site has multiple monorepo blocks installed.

Code Standards.

This repo uses branch protection. Anything on PR to the trunk branch will be subject to review. Please ensure you test your PR with the following:

  1. Your PR should represent a single block plugin, block dependencies are the only exception to this.
  2. Your PR should be tested with PHPCS + WPCS, we use WordPress-Extra as the main standard and include a few extra standards via the phpcs.xml file in the project root.
  3. Your PR should be linted using the tools provided by @wordpress/scripts, this includes tools for formatting JS/CSS and linting JS/CSS