How to create custom blocks in Drupal using a custom module

Here we are going to discuss how to create blocks programmatically with our custom module. 

As you know we can create blocks in Drupal using admin GUI, but in some cases developers may need more control over the configurations, rendered fields and customised logic while saving the configuration.

So here we are going to discuss below points in this article.

  • Create a simple block which display text content
  • Custom block with Custom form as block content
  • Custom Block with custom configuration form

Create a simple block which display text content

Here we are going to create a simple block which will display text content in the region in which  it is assigned.

First Create  SampleBlock. php file in  below path in your custom module.

/src/Plugin/Block/SampleBlock.php

So in SampleBlock.php file extend class with  \Core\Block\BlockBase 

 Below block annotation is very important  which provides machine name as id and admin label which will be appearing in block list page.place below block before starting the class.

/**

* Provides a ‘Sample: Simple Block’ block.

*

* @Block(

*   id = “sample_simple_block”,

*   admin_label = @Translation(“Sample: Simple Block”)

* )

*/

Also you can add category as category = @Translation(“Custom”), so in the list of block you can see your custom block under custom category.

Next is a  build function implementation as below, which will return a text “Sample Block”.

public function build() {

   return [

     ‘#markup’ => $this->t(“Sample Block”),

   ];

 }

So complete code of SampleBlock.php is provided below.

<?php
 
namespace Drupal\dn_block\Plugin\Block;
 
use Drupal\Core\Block\BlockBase;
 
/**
* Provides a 'Sample: Simple Block' block.
*
* @Block(
*   id = "sample_simple_block",
*   admin_label = @Translation("Sample: Simple Block")
* )
*/
class SampleBlock extends BlockBase {
 
 /**
  * {@inheritdoc}
  */
 public function build() {
   return [
     '#markup' => $this->t("Sample Block"),
   ];
 }
 
}

Here dn_block is our custom module name,

Clear the cache and go to the block listing page in path /admin/structure/block.

Click on place against Sidebar first region,

You can see  sample block in block listing page.

Click on the place block button and save the block layout page, you can see below the left side in sidebar region, displaying our custom block text.

Custom block with Custom form as block content

Here we are going to discuss how to load a custom form in our custom block.

So we have below custom form in module path /src/Form/StudentForm.php

<?php
 
namespace Drupal\dn_block\Form;
 
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;
 
/**
* Provides the form for adding countries.
*/
class StudentForm extends FormBase {
 
 /**
  * {@inheritdoc}
  */
 public function getFormId() {
   return 'dn_student_form';
 }
 
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state) {
 
 
  
   $form['fname'] = [
     '#type' => 'textfield',
     '#title' => $this->t('First Name'),
     '#required' => TRUE,
     '#maxlength' => 20,
     '#default_value' =>  '',
   ];
  $form['sname'] = [
     '#type' => 'textfield',
     '#title' => $this->t('Second Name'),
     '#required' => TRUE,
     '#maxlength' => 20,
     '#default_value' =>  '',
   ];
 $form['age'] = [
     '#type' => 'textfield',
     '#title' => $this->t('Age'),
     '#required' => TRUE,
     '#maxlength' => 20,
     '#default_value' => '',
   ];
  $form['marks'] = [
     '#type' => 'textfield',
     '#title' => $this->t('Marks'),
     '#required' => TRUE,
     '#maxlength' => 20,
     '#default_value' => '',
   ];
    $form['actions']['#type'] = 'actions';
   $form['actions']['submit'] = [
     '#type' => 'submit',
     '#button_type' => 'primary',
     '#default_value' => $this->t('Save') ,
   ];
  //$form['#validate'][] = 'studentFormValidate';
 
   return $form;
 
 }
   /**
  * {@inheritdoc}
  */
 public function validateForm(array & $form, FormStateInterface $form_state) {
      $field = $form_state->getValues();
   
   $fields["fname"] = $field['fname'];
   if (!$form_state->getValue('fname') || empty($form_state->getValue('fname'))) {
           $form_state->setErrorByName('fname', $this->t('Provide First Name'));
       }
  
  
 }
 
 /**
  * {@inheritdoc}
  */
 public function submitForm(array & $form, FormStateInterface $form_state) {
 try{
  
  
   $field = $form_state->getValues();
   
    $this->messenger()->addMessage($this->t('The form has been submitted. name="@first @last"', [
     '@first' => $field['fname'],
     '@last' => $field['sname']
   ]));
  
    
 } catch(Exception $ex){
   \Drupal::logger('dn_block')->error($ex->getMessage());
 }
  
 }
 
}

So its a simple form with basic text fields. After submission this will display a message with submitted names. 

So we are going to render this form in our custom block. For this render custom form within block render array as below in SampleBlock.php

public function build() {
   $form = \Drupal::formBuilder()->getForm('Drupal\dn_block\Form\StudentForm');
   return [
     '#markup' => $this->t("Sample Block"),
     'form' => $form
   ];
 }

Clear the cache and open page you have side bar first region, you can see form as below.

Custom Block with custom configuration form

Here we are going to discuss below three  functions for creating custom configurations.

  • blockForm() – This method defines form elements for custom block configuration.
  • blockSubmit() This method processes the blockForm() form fields when the block configuration form is submitted.
  • defaultConfiguration()This method sets the block default configuration. This configuration determines the block’s behavior when a block is initially placed in a region.

In order to  experiment above functions, we are creating another sample block in below path  /src/Plugin/Block/SampleConfigBlock.php

Below provided id and admin label for the new block.

/**

* Provides a ‘Sample: Simple Block’ block.

*

* @Block(

*   id = “sample_config_block”,

*   admin_label = @Translation(“Sample: Config Block”)

* )

*/

defualtConfiguration()

First implement defaultconfiguration function.

This method sets the block default configuration. This configuration  determines the block’s behavior when a block is initially placed in a region.

In our example we are initialising a variable block_sample_string.

public function defaultConfiguration() {
     return [
       'block_sample_string' => $this->t('A default value. This block was created at %time', ['%time' => date('c')]),
     ];
   }

blockForm() 

This method defines form elements for custom block configuration.  We are returning a text area field in this function as provided below.

public function blockForm($form, FormStateInterface $form_state) {
     $form['block_sample_string_text'] = [
       '#type' => 'textarea',
       '#title' => $this->t('Block contents'),
       '#description' => $this->t('This text will appear in the sample block.'),
       '#default_value' => $this->configuration['block_sample_string'],
     ];
     return $form;
   }

blockSubmit()

This method processes the blockForm() form fields when the block  configuration form is submitted.  The blockValidate() method can be used to validate the form submission.

public function blockSubmit($form, FormStateInterface $form_state) {
     $this->configuration['block_sample_string']
       = $form_state->getValue('block_sample_string_text');
   }

Here we are setting block_sample_string value as value of form field block_sample_string_text.

Finally we are rendering the final value of block_sample_string as below.

public function build() {
   return [
       '#markup' => $this->configuration['block_sample_string'],
     ];
 }

Clear the cache, while placing the block you can see our custom configuration field block contents initiated with our value set in defaultConfiguration function.

Other Block functions that can be used are provided below.

access()

Using this function we can control visibility of block with conditions like below.

public function access(AccountInterface $account, $return_as_object = FALSE) {

    return \Drupal\Core\Access\AccessResult::allowedIf($account->isAuthenticated());

  }

getCacheMaxAge

We can change the block cache max time to 0 as below.

public function getCacheMaxAge() {

    // If you want to disable caching for this block.

    return 0;

  }

 

Complete source codes of above sample blocks can be downloaded here

Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...