Eigenen Block für Drupal 8 programmieren

Mit der neuen Plugin API in Drupal 8 ist es sehr einfach, eigene (instanzierte) Blöcke zu entwickeln. Durch die neue Instanzierung kann ein Block mehrfach verwendet/platziert werden und auch unterschiedliche Einstellungen besitzen.

Um den eigenen Block verfügbar zu machen, muss einmal das Grundgerüst für ein Modul angelegt sein, und eine Klasse für den Block implementiert werden.

In dem folgenden Beispiel zeige ich, wie man einen Block mit Hilfe der neuen Plugin API implementiert, welches ein einfaches Formular enthält und anschließend „Hello [dein Name]!“ ausgibt.

In Drupal 8 stehen die Basis Funktionen nicht mehr in der *.module Datei, sondern jede Klasse wird in einer eigenen Datei implementiert, die meist in einer ganz bestimmten Ordnerstruktur (PSR-0 oder PSR-4) abgelegt sein muss. Daher legen wir in unserem Modul Ordner (im Beispiel heißt das Modul „mein_modul“) die Ordnerstruktur src/Plugin/Block an. In dem Ordner Block erstellen wir dann die PHP-Datei DemoBlock.php, in der wir unsere DemoBlock Klasse implementieren:

<?php
// mein_modul/src/Plugin/Block/DemoBlock.php
 
namespace Drupal\mein_modul\Plugin\Block;
 
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
 
/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */
class DemoBlock extends BlockBase {
 
  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);
    $config = $this->getConfiguration();
 
    $form['name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Your name'),
      '#default_value' => isset($config['name']) ? $config['name'] : '',
    );
 
    return $form;
  }
 
  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->setConfigurationValue('name', $form_state->getValue('name'));
  }
 
  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this->getConfiguration();
    $name = isset($config['name']) ? $config['name'] : '';
 
    return array(
      '#markup' => $this->t('Hello @name!', array('@name' => $name)),
    );
  }
 
}

Unsere gesamte Block Funktionalität wird komplett in unserer eigenen DemoBlock Klasse implementiert. Diese baut dabei auf die Basis-Blockimplementierung von Drupal 8 BlockBase auf. Dadurch, müssen wir viele Sachen nicht immer neu implementieren, können aber auf Wunsch bestimmte Teile der Basisimplementierung überschreiben und/oder erweitern.

In dem Kommentar über der Klassenimplementierung sehen wir auch eine weitere Neuerung in Drupal 8: die „Annotations“. Dies sind spezielle Kommentare @Block( ... ), die Informationen (in diesem Fall zu unserem Block) bereitstellen. Sie sind vergleichbar mit dem hook_block_info Hook aus Drupal 7. Hier vergeben wir die ID demo_block für unseren Block und nennen ihn Demo Block (wobei der Name wiederum mit dem Translation System verarbeitet wird).

Ansonsten besteht unsere Klasse aus den drei Funktionen blockForm() (welche das Konfigurationsformular bereitstellt), blockSubmit() (was die Werte aus dem Formular speichert) und build(). Die build() Funktion ist dabei die entscheidende, da diese die Ausgabe des Blocks auf der Website steuert.

Nachdem wir unser Modul aktiviert und den Cache geleert haben, steht unser Modul unter „Blocklayout“ (/admin/structure/block) für die Platzierung auf der Website zur Verfügung.