Block API
Overview
Blocks in Drupal 8 actually consist of two separate API structures to create a user interface similar to previous iterations of Drupal. These two APIs are the Block Plugin API, which is a reusable standalone API, and the Block Entity API, which is a Drupal 8-specific implementation for placing blocks and controlling their visibility.
Creating Blocks with the Block Plugin API
To define blocks in your module's code, you’ll need to learn and understand the Plugin API and, in particular, the concept of annotation-based plugin discovery, which is the mechanism Drupal 8 uses to find your block definition code.
Creating a custom block defined in your module includes the following steps:
- Create a block plugin using annotations.
- Extend the Drupal\Core\Block\BlockBase class.
- Implement methods from the BlockPluginInterface as needed.
Making Your Block Visible to Drupal and Users
Drupal uses PSR-4 standard for discovery. Assuming your module is named "fax", the code for your custom block(s) should be placed in fax/src/Plugin/Block/
. Each file in that directory must be named according to the class it contains. If we are defining a class called FaxBlock
, it should be in a file named fax/src/Plugin/Block/FaxBlock.php
and contain the following example content:
namespace Drupal\fax\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * Provides a 'Fax' block. * * @Block( * id = "fax_block", * admin_label = @Translation("Fax block"), * ) */ class FaxBlock extends BlockBase { // Override BlockPluginInterface methods here. }
The id
in the annotation defines the unique machine-readable ID of your block, and the admin_label
defines a human-readable name shown in the admin UI. Available annotation properties are defined in \Drupal\Core\Block\Annotation\Block.
The two most common methods to override are:
BlockPluginInterface::build()
– returns a render array for the block’s content.BlockBase::access()
– controls block visibility and should return anAccessResult
object.
Adding Custom Configuration Options to Your Block
You can add custom configuration options to the block config form by overriding blockForm()
and blockSubmit()
, using setConfigurationValue()
and getConfiguration()
.
Example of a block with a configurable fax number:
use Drupal\Core\Block\BlockBase; use Drupal\Core\Form\FormStateInterface; /** * Provides a 'Fax' block. * * @Block( * id = "fax_block", * admin_label = @Translation("Fax block"), * ) */ class FaxBlock extends BlockBase { public function build() { $config = $this->getConfiguration(); $fax_number = isset($config['fax_number']) ? $config['fax_number'] : ''; return [ '#markup' => $this->t('The fax number is @number!', ['@number' => $fax_number]), ]; } public function blockForm($form, FormStateInterface $form_state) { $form = parent::blockForm($form, $form_state); $config = $this->getConfiguration(); $form['fax_number'] = [ '#type' => 'textfield', '#title' => $this->t('Fax number'), '#default_value' => $config['fax_number'] ?? '', ]; return $form; } public function blockSubmit($form, FormStateInterface $form_state) { $this->setConfigurationValue('fax_number', $form_state->getValue('fax_number')); } public function blockValidate($form, FormStateInterface $form_state) { $fax_number = $form_state->getValue('fax_number'); if (!is_numeric($fax_number)) { $form_state->setErrorByName('fax_number', $this->t('Needs to be an integer')); } } }
You can also use getConfiguration()
in build()
to display config data to users. The access()
method can contain complex logic to control visibility.
Example of an access control method:
public function access(AccountInterface $account, $return_as_object = FALSE) { return \Drupal\Core\Access\AccessResult::allowedIf($account->isAuthenticated()); }
Example with cache tags (learn more about cache tags):
public function getCacheTags() { return \Drupal\Core\Cache\Cache::mergeTags(parent::getCacheTags(), ['node_list']); }
Disable caching by setting max-age to 0:
public function getCacheMaxAge() { return 0; }
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.