Wednesday 13 March 2019

Create Configurable Block Programmatically Drupal 8

Configurable custom block programmatically

Create a block having form to configure company contact details on block configuration page.

Drupal 8 Annotation

Drupal 8 Annotations-based Plugin discovery mechanism reads the annotation meta-data and confirms that particular plugin is implementation of block or FieldFormatter or FieldWidgets or RestResources or all views plugins etc. With this it implement plugin interface like BlockPluginInterface or ResourceInterface etc.
In the current scenario, Annotation is for block and it implementing BlockPluginInterface which provides methods like build() and blockForm().
Annotation in this case provides machine readable name, admin label, category.

Contact details form
Contact details form should have following fields: company_name, company_email, company_address, company_telephone.
To create custom block follow the custom block. We extends "BlockBase" to create custom block.

<?php
/**
 * @file
 * Contains \Drupal\firstcustommodule\Plugin\Block\CompanyContactBlock.
 */
namespace Drupal\firstcustommodule\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;  
/**
 * Provides a 'Company Contact' block.
 *
 * @Block(
 *   id = "company_contact_block",
 *   admin_label = @Translation("Company Contact Us"),
 *   category = @Translation("Custom company contact us block")
 * )
 */
class CompanyContactBlock extends BlockBase {
  /**
   * {@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['company_name'] = array(
      '#type' => 'textfield',
      '#title' => t('Company Name:'),
      '#default_value' => isset($config['company_name'])? $config['company_name'] : '',
    );
    $form['company_mail'] = array(
      '#type' => 'email',
      '#title'=> t('Company Email ID:'),
      '#default_value' => isset($config['company_mail'])? $config['company_mail'] : '',
    );
    $form['company_telephone'] = array(
      '#type' => 'number',
      '#title'=> t('Company Contact:'),
      '#default_value' => isset($config['company_telephone'])? $config['company_telephone'] : '',
    );
    $form['company_adddress'] = array(
      '#type' => 'textfield',
      '#title'=> t('Company Address:'),
      '#default_value' => isset($config['company_adddress'])? $config['company_adddress'] : '',
    );
    return $form;
  }
  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    // Save our custom settings when the form is submitted.
    $this->setConfigurationValue('company_name', $form_state->getValue('company_name'));
    $this->setConfigurationValue('company_mail', $form_state->getValue('company_mail'));
    $this->setConfigurationValue('company_telephone', $form_state->getValue('company_telephone'));
    $this->setConfigurationValue('company_adddress', $form_state->getValue('company_adddress'));
  }
  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this->getConfiguration();
    $company_name = isset($config['company_name']) ? $config['company_name'] : '';
    $company_mail = isset($config['company_mail']) ? $config['company_mail'] : '';
    $company_telephone = isset($config['company_telephone']) ? $config['company_telephone'] : '';
    $company_address = isset($config['company_adddress']) ? $config['company_adddress'] : '';
    return array(
      '#markup' => $this->t('@comp, Email id : @mail Phn: @phone. Address: @address', array('@address'=> $company_address,'@phone'=> $company_telephone,'@mail'=> $company_mail,'@comp'=> $company_name)),
    );
  }
  /**
   * {@inheritdoc}
   */
  public function blockValidate($form, FormStateInterface $form_state) {
    $company_name = $form_state->getValue('company_name');
    if (is_numeric($company_name)) {
      drupal_set_message('needs to be an integer', 'error');
      $form_state->setErrorByName('company_name', t('Company name should not be numeric'));
    }
  }
}


Explanation of above code

class in above code provides the generic block configuration form, default block settings, and handling for general user-defined block visibility settings.

$form = parent::blockForm($form, $form_state);

Above line creates a form array and get all the data from the parent method.

  /**
   * {@inheritdoc}
   */
  public function setConfigurationValue($key, $value) {
    $this->configuration[$key] = $value;
  }

Above method is defined in BlockBase class as shown above and is declared in BlockPluginInterface.
Now in above CompanyContactBlock, setConfigurationValue() method is used to save/set block configuration data.

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    // code comes here.
 }
Above method is defined in BlockBase class as shown above and is declared in BlockPluginInterface. If there is no error then blockSubmit() method processes block submission handlers.

/**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this->getConfiguration();
  }
Above method is declared in BlockPluginInterface. This is defined in the current class. This method gets the block configuration.


/**
   * {@inheritdoc}
   */
  public function blockValidate($form, FormStateInterface $form_state) {
// some code here
}
Above method is to add validation to block.
Above method is defined in BlockBase class as shown above and is declared in BlockPluginInterface.

After saving above file with code, then this block will start to appear in structure > Block Layout.
Now place this block in any region and go to block configuration page. Block configuration page will look as shown in screenshot.

Save this form with the values.
Suppose I want to display this block in second_sidebar region of the page.









Then this block will look as shown in screenshot.







No comments:

Post a Comment