Blocks are building blocks of Drupal website. Each content in a Drupal website belongs to one block or other. Blocks can be easily displayed in different part of the webpage using regions in themes.
There are two types of custom blocks in Drupal:
- Create using Drupal Graphical User Interface(GUI) system through /admin/structure/block/block-content
- Programmatically create based on your requirement
Let's see each method in more detail below.
Create a custom block using Drupal GUI
Creating a custom block using Drupal GUI is easy as in Drupal 9 all the custom content blocks are referred as 'Custom block'. You could create a new custom block by in the admin menu Structure >> Block layout >> Add custom block.
You can create different types of block as same as different type of nodes. Block types can be managed in Structure >> Block layout >> Block types. Blocks are also fieldable entities in Drupal 9. It is possible to add different types of fields to a bock type. Similar to content types, you could navigate to manage fields from Block types page.
Programmatically create a custom block
Blocks are plugins in Drupal. Custom plugin can be created using a custom module. So in this example, we name the module as ddocs_simple_block.
First create a folder under custom block directory of Drupal docroot. ie: docroot/modules/custom/ddocs_simple_block
Then create the info.yml file with module meta info that helps Drupal core to identify the custom module.
type: module
description: 'DevelopersDocs simple block demo module.'
package: DDocs
core_version_requirement: ^8 || ^9
Create the custom plugin by extending the core BlockBase class. The new class file should place inside docroot/modules/custom/ddocs_simple_block/src/Plugin/Block directory.
namespace Drupal\ddocs_simple_block\Plugin\Block;
/**
* Provides DDocs simple block.
*
* @Block(
* id = "ddocs_dimple_block",
* admin_label = @Translation("DDocs Simple Block"),
* category = @Translation("DDocs")
* )
*/
class DdocsSimpleBlock extends BlockBase {
public function build()
{
return [
'#markup' => 'Welcome to DDocs!'
];
}
}
If you want to cache the block per node and need to rebuild the block based on 'route' add following method to your class.
//With this when your node change your block will rebuild
if ($node = \Drupal::routeMatch()->getParameter('node')) {
//if there is node add its cachetag
return Cache::mergeTags(parent::getCacheTags(), array('node:' . $node->id()));
} else {
//Return default tags instead.
return parent::getCacheTags();
}
}
public function getCacheContexts() {
//if you depends on \Drupal::routeMatch()
//you must set context of this block with 'route' context tag.
//Every new route this block will rebuild
return Cache::mergeContexts(parent::getCacheContexts(), array('route'));
}
Then custom block class finally looks like below:
namespace Drupal\ddocs_simple_block\Plugin\Block;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Block\BlockBase;
/**
* Provides DDocs simple block.
*
* @Block(
* id = "ddocs_dimple_block",
* admin_label = @Translation("DDocs Simple Block"),
* category = @Translation("DDocs")
* )
*/
class DdocsSimpleBlock extends BlockBase {
public function build()
{
return [
'#markup' => 'Welcome to DDocs!'
];
}
public function getCacheTags() {
//With this when your node change your block will rebuild
if ($node = \Drupal::routeMatch()->getParameter('node')) {
//if there is node add its cachetag
return Cache::mergeTags(parent::getCacheTags(), array('node:' . $node->id()));
} else {
//Return default tags instead.
return parent::getCacheTags();
}
}
public function getCacheContexts() {
//if you depends on \Drupal::routeMatch()
//you must set context of this block with 'route' context tag.
//Every new route this block will rebuild
return Cache::mergeContexts(parent::getCacheContexts(), array('route'));
}
}
A new block "DDocs Simple Block" now should be available under Block layout page, and we can assign it to the required region by using the Place block button next to each region name.
Hope this helps you to create a custom block programmatically based on your requirement. Cheers! :) ????