Drupal 8: Sample Module

Introducing Block Plugins & Configuration Forms
Drupal Meetup Stuttgart

03/05/2015

 

1. Tell Drupal about the module

name: Temperature
type: module
description: 'Creates a configurable block showing the local temperature'
package: Meetup
version: '1.0.0'
core: '8.x'

modules/custom/temperature/temperature.info.yml

2. Create a simple block plugin

<?php

/**
 * @file
 * Contains \Drupal\temperature\Plugin\Block\TemperatureBlock.
 */

namespace Drupal\temperature\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'Temperature' block.
 *
 * @Block(
 *   id = "temperature",
 *   admin_label = @Translation("Local temperature"),
 *   category = @Translation("Meetup")
 * )
 */
class TemperatureBlock extends BlockBase {

  public function build() {

    return [
      '#markup' => 'Seems cold outside!',
    ];

  }

}

modules/custom/temperature/src/Plugin/Block/TemperatureBlock.php

use GuzzleHttp\Client;

class TemperatureBlock extends BlockBase {

  public function build() {
    $city = 'Stuttgart, DE'
    $client = new Client();
    $response = $client->get("http://api.openweathermap.org/data/2.5/weather?q=$city");
    if ($response->getStatusCode() == '200') {
      $result = json_decode($response->getBody());
      $markup = "Current temperature in<br>$city:<br>";
      $markup .= round($result->main->temp - 273.15) . '° C';
    }
    else {
      $markup = 'Sorry, something went wrong!';
    }
    return [
      '#markup' => $markup,
    ];
  }

}

Adding the "real" content

3. Make block instances configurable

block.settings.temperature:
  type: block_settings
  label: 'Temperature block'
  mapping:
    city:
      type: string
      label: 'City for temperature display'

modules/custom/temperature/config/schema/temperature.schema.yml

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;

class TemperatureBlock extends BlockBase {

  public function build() {
    $city = $this->configuration['city'];
    ...
  }

  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form['city'] = array(
      '#title' => 'Location',
      '#type' => 'textfield',
      '#default_value' => $this->configuration['city'],
    );
    return $form;
  }

  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['city'] = $form_state->getValue('city');
    $this->blockSubmit($form, $form_state);
  }

}

modules/custom/temperature/src/Plugin/Block/TemperatureBlock.php

4. Provide a default configuration

temperature.settings:
  type: mapping
  label: 'Temperature settings'
  mapping:
    city:
      type: string
      label: 'Default city for temperature display'
block.settings.temperature:
  type: block_settings
  label: 'Temperature block'
  mapping:
    city:
      type: string
      label: 'City for temperature display'

modules/custom/temperature/config/schema/temperature.schema.yml

modules/custom/temperature/config/install/temperature.settings.yml

city: 'Stuttgart,DE'
...

class TemperatureBlock extends BlockBase {

  public function defaultConfiguration() {
    $config = \Drupal::config('temperature.settings')->get();
    return $config;
  }

  public function build() {
    ...
  }

  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form['city'] = array(
      '#title' => 'Location',
      '#type' => 'textfield',
      '#default_value' => $this->configuration['city'],
    );
    return $form;
  }

  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['city'] = $form_state->getValue('city');
    $this->blockSubmit($form, $form_state);
  }

}

modules/custom/temperature/src/Plugin/Block/TemperatureBlock.php

5. Make default configuration editable

temperature.settings:
  path: '/admin/config/system/temperature'
  defaults:
    _form: 'Drupal\temperature\Form\SettingsForm'
    _title: 'Temperature settings'
  requirements:
    _permission: 'administer site configuration'

modules/custom/temperature/temperature.routing.yml

<?php

/**
 * @file
 * Contains \Drupal\temperature\Form\SettingsForm
 */

namespace Drupal\temperature\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class SettingsForm extends ConfigFormBase {

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);
    $form['city'] = [
      '#title' => 'Default Location',
      '#type' => 'textfield',
      '#default_value' => $this->config('temperature.settings')->get('city'),
    ];
    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->config('temperature.settings')
      ->set('city', $form_state->getValue('city'))
      ->save();
    parent::submitForm($form, $form_state);
  }

  protected function getEditableConfigNames() {
    return ['temperature.settings'];
  }

  public function getFormId() {
    return 'temperature_settings';
  }
}

modules/custom/temperature/src/Form/SettingsForm.php

Thank You!

 

http://slides.com/drubb

http://slideshare.net/drubb

Building a sample Drupal 8 Module

By Boris Böhne

Building a sample Drupal 8 Module

Building a small Drupal 8 sample module, a presentation at Drupal Meetup Stuttgart, 03/05/2015

  • 1,599