Skip to content

Essential APIs - Block

From Block API Overview on Drupal.org updated July 2024: Blocks in Drupal are actually made up of two separate API structures to create a user experience similar to what Drupal has maintained in past iterations. These two APIs are the Block Plugin API, which is a stand-alone reusable API and the Block Entity API which is a Drupal specific use case of block placement and visibility control.

The Block Plugin API remains part of the core plugin system, allowing developers to define reusable, programmatically-created blocks by extending the BlockBase class. Plugins are defined in code and registered via annotations.

The Block Entity API is part of the Custom Block module (renamed as Block Content module). It allows site builders and content editors to manage blocks as content entities with revisions, fields, and translations.

Make sure you understand the Plugin API before continuing.

Steps for setting up a custom block:

  • Create block plugin using annotations
  • Extend the Drupal\Core\Block\BlockBase class
  • Implement the necessary methods from the Drupal\Core\Block\BlockPluginInterface

Example from Block API Overview:

php
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
/**
 * Provides a 'Fax' block.
 *
 * @Block(
 *   id = "fax_block",
 *   admin_label = @Translation("Fax block"),
 * )
 */
class FaxBlock extends BlockBase {

  // Access  method here ...

  /**
   * {@inheritdoc}
   */
  public function build() {

  $config = $this->getConfiguration();
    $fax_number = isset($config['fax_number']) ? $config['fax_number'] : '';
    return array(
      '#markup' => $this->t('The fax number is @number!', array('@number' => $fax_number)),
    );  
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);

    // Retrieve existing configuration for this block.
    $config = $this->getConfiguration();

    // Add a form field to the existing block configuration form.
    $form['fax_number'] = array(
      '#type' => 'textfield',
      '#title' => t('Fax number'),
      '#default_value' => isset($config['fax_number']) ? $config['fax_number'] : '',
    );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    // Save our custom settings when the form is submitted.
    $this->setConfigurationValue('fax_number', $form_state->getValue('fax_number'));
  }

  /**
   * {@inheritdoc}
   */
  public function blockValidate($form, FormStateInterface $form_state) {
    $fax_number = $form_state->getValue('fax_number');

    if (!is_numeric($fax_number)) {
      $form_state->setErrorByName('fax_block_settings', t('Needs to be an integer'));
    }
  }
}
  1. hook_block_access()
    • Purpose: Control block access dynamically based on custom conditions.
    • Use Case: Restrict blocks to specific user roles or permissions.
  2. hook_block_view_alter()
    • Purpose: Alter the render array of a block before it is displayed on the page.
    • Use Case: Modify block content dynamically, add classes, or insert extra elements.
    • Block specific: hook_block_build_BASE_BLOCK_ID_alter()
  3. hook_block_alter()
    • Purpose: Modify block objects after they are loaded from storage.
    • Use Case: Change block properties such as title, configuration, or settings dynamically.
    • Block specific: hook_block_view_BASE_BLOCK_ID_alter()

Older Drupal 7 Hooks

  • hook_block_configure_alter
  • hook_block_info_alter
  • hook_block_list_alter

Additional information for Hooks provided by the Block module

Questions

General

What are the different APIs that make up what is commonly referred to as the Block API and what are their purpose?

Block Plugin API and the Block Entity API: The Block Plugin API is a stand-alone reusable API, and the Block Entity API which is a Drupal use case of the block placement and visibility control.

What are the 3 steps of creating a custom block?
  • Create a block plugin using annotations
  • Extend the Drupal\Core\Block\BlockBase class
  • Implement the methods from the Drupal\Core\Block\BlockPluginInterface interface needed for your use case

Backend Developer (Advanced)

Which method must be implemented when creating a custom block plugin?

build()

When creating a custom block plugin, how do you define its administrative label?

Using an annotation in the block plugin class

If a block needs to display dynamic content based on the current node being viewed, which caching mechanism should you use?

Override the getCacheContexts() method to add the route context

php
public function getCacheContexts() {
    // This example breaks bubbling of cacheable metadata
    return ['url.path', 'url.query_args'];
}

Resources