Creating Custom Drupal Blocks with the Block Plugin API

As a Drupal developer, there will inevitably be a time when the stock block types provided just don’t cut it. Maybe you need to display data from an external API or create a specialized widget for editors. Whatever the case, Drupal’s Block Plugin API makes it easy to create your own custom blocks with PHP. Today, I’ll walk you through the basics of building and configuring a custom block in Drupal 9 or 10.

Why Use Custom Blocks?

Custom blocks let you go beyond the capabilities of core and contributed modules. They’re perfect for integrating dynamic content, custom forms, or any other feature you want to appear in your site’s layout regions. Using the Block Plugin API ensures your work follows Drupal best practices and takes advantage of caching and configuration management.

Step 1: Generate a Custom Module

First, generate a module to contain your block. You can do this manually or with Drush:

drush generate module

Let’s call it custom_widgets. Your module will need a .info.yml file at modules/custom/custom_widgets/custom_widgets.info.yml.

Step 2: Create the Block Plugin

Within your module, create a src/Plugin/Block/ directory. Add a new PHP class for your block, for example: modules/custom/custom_widgets/src/Plugin/Block/WeatherBlock.php.

Here’s a simple example block:

namespace Drupal\custom_widgets\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'Weather Update' Block.
 *
 * @Block(
 *   id = "weather_block",
 *   admin_label = @Translation("Weather Update")
 * )
 */
class WeatherBlock extends BlockBase {
  public function build() {
    // In a real scenario, fetch weather data from an API.
    return [
      '#markup' => $this->t('The current temperature is 20°C.'),
    ];
  }
}

Clear the Drupal cache so the system recognizes your new block:

drush cr

Step 3: Place Your Block

Head to the block layout page (/admin/structure/block) and place your Weather Update block anywhere in your theme’s regions.

Step 4: Add Configuration (Optional)

To make your block more flexible, add a configuration form by extending BlockBase’s blockForm() and blockSubmit() methods. This lets editors set block-specific properties, such as choosing the city for the weather data.

Final Tips

  • Always use dependency injection if your block needs services.
  • Leverage caching contexts and tags for performance.
  • Keep your code organized in your custom module folder structure.

Custom blocks are a core Drupal feature every site builder should master! They provide a maintainable, reusable approach to extending your layouts in powerful ways.

Happy coding, and let me know if you have any custom block tricks to share! — Drew

Comments

One response to “Creating Custom Drupal Blocks with the Block Plugin API”

  1. Geneva Avatar
    Geneva

    Great article, Drew! You’ve provided a clear, actionable walkthrough of the custom block creation process—perfect for both Drupal newcomers and seasoned site builders looking to extend their layouts. I especially appreciate your emphasis on configuration options and best practices like dependency injection and caching, which are essential for scalable, maintainable Drupal solutions.

    For anyone working with dynamic or AI-powered content, custom blocks are a fantastic integration point. For example, you can use AI coding agents to generate or personalize block content on the fly, or even automate the creation of new blocks based on editorial prompts. With Drupal’s plugin architecture, it’s straightforward to inject external services—like language models or analytics APIs—directly into your custom blocks using dependency injection.

    One tip for readers: If you find yourself adding lots of logic or external dependencies, consider breaking functionality into dedicated services and keeping your block classes focused on presentation and configuration. This makes it easier to test and maintain your code, especially as your module grows.

    Thanks for sharing this practical guide!
    — Geneva

Leave a Reply

Your email address will not be published. Required fields are marked *