Porting a Drupal 7 module to Drupal 8 (a real life example) #3- configuration form

Drupal 8’s beta version was released a few month ago and now it is time to start porting modules. To demonstrate how to do it, we’re going to use a real module called scroll_to_top, which allow us to scroll to top when we are reading an article and we want to go to the menu for example.

If you prefer watching videos, here is the screencast version of this series.

Drupal modules often provide an administrator with a settings page so that various configuration options can be tuned and setup using the web interface. In this chapter we are going to explore to create a configuration form and save values in the configuration management.

Adding default values.

In Drupal 7 we used to use the function variable_get($variable_name, $default_value); to get a setting value. Here if a variable with the name $variable_name doesn’t exist the it returns $default_value,so we can say that this is the way to configure default values in Drupal 7. But variable_get() was removed and we have to use the new configuration management system and the API to access to settings value. But don’t worry, we can specify default configuration values for configuration yet, however, it is done in a different way and file :).

In Drupal 8 a module can provide default configuration in a YAML file located in the config/install folder in the module root directory. The convention for naming this file is to prefix it with the name of the module. So let’s create one called scroll_to_top.settings.yml

scroll_to_top.settings.yml

label: 'Back to top'
position: 1
hover: '#777777'
bg_color_out: '#CCCCCC'
display_text: true
admin_theme: true

Now, I’m so sorry but to make this work you need to reinstall the module 😛

what?

Did you do it? So, we can start now porting our configuration form and create the settings page.

Configuration Form conversion

If we see the file scroll_to_top.module of the Drupal 7 version, in the chunk of code where it defines its menu links we will note that there is a key-value 'file' => 'scroll_to_top.admin.inc'. That means the function that is going to be called when the user click on the link is in that file, so if we now open that file we are going to see the following function.

scroll_to_top.admin.inc

<?php

/**
 * @file
 * Administration page for scroll to top module
 *
 */

function scroll_to_top_settings() {
$form = array();
  $form['scroll_to_top_label'] = array(
    '#type' => 'textfield',
    '#title' => t('Label'),
    '#description' => t('label displayed in scroll to top link, default "Back to top".'),
    '#default_value' => variable_get('scroll_to_top_label', t('Back to top')),
    '#size' => 10,
  );
  
  $form['scroll_to_top_position'] = array(
    '#title' => t('Position'),
    '#description' => t('Sroll to top button position'),
    '#type' => 'select',
    '#options' => array(
      1 => t('right'),
      2 => t('left'),
      3 => t('middle'),
    ),
    '#default_value' => variable_get('scroll_to_top_position', 0.5),
  );
  $form['scroll_to_top_bg_color_hover'] = array(
    '#type' => 'textfield',
    '#title' => t('Background color on mouse over.'),
    '#description' => t('Button background color on mouse over default #777777'),
    '#default_value' => variable_get('scroll_to_top_bg_color_hover', '#777777'),
    '#size' => 10,
    '#maxlength' => 7,
  );
  $form['scroll_to_top_bg_color_out'] = array(
    '#type' => 'textfield',
    '#title' => t('Background color on mouse out.'),
    '#description' => t('Button background color on mouse over default #CCCCCC'),
    '#default_value' => variable_get('scroll_to_top_bg_color_out', '#CCCCCC'),
    '#size' => 10,
    '#maxlength' => 7,
  );
  $form['scroll_to_top_display_text'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display label'),
    '#description' => t('Display "BACK TO TOP" text under the button'),
    '#default_value' => variable_get('scroll_to_top_display_text', TRUE),
  );
  $form['scroll_to_top_enable_admin_theme'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable on administration theme.'),
    '#description' => t('Enable scroll to top button on administartion theme.'),
    '#default_value' => variable_get('scroll_to_top_enable_admin_theme', TRUE),
  );
  $form['scroll_to_top_preview'] = array(
    '#type' => 'item',
    '#title' => t('Preview'),
    '#markup' => '<div id="scroll-to-top-prev-container">' . t('Change a setting value to see a preview. "Position" and "enable on admin theme" not included.') . '</div>',
  );
  return system_settings_form($form);
}

Now, let’s convert this into the a configuration form in src/Form/ScrollToTopForm.php

ScrollToTopForm.php

<?php

/**
* @file
* Contains \Drupal\scroll_to_top\Form\ScrollToTopForm
*/

namespace Drupal\scroll_to_top\Form;

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

class ScrollToTopForm extends ConfigFormBase {

  /**
  * {@inheridoc}
  */
  public function getFormId() {
    return 'scroll_to_top_form';
  }
  
  /**
  * {@inheridoc}
  */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('scroll_to_top.settings');

    $form['scroll_to_top_label'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#description' => t('label displayed in scroll to top link, default "Back to top".'),
      '#default_value' => $config->get('label'),
      '#size' => 10,
    );

    $form['scroll_to_top_position'] = array(
      '#title' => $this->t('Position'),
      '#description' => $this->t('Sroll to top button position'),
      '#type' => 'select',
      '#options' => array(
        1 => t('right'),
        2 => t('left'),
        3 => t('middle'),
      ),
      '#default_value' => $config->get('position'),
    );
    $form['scroll_to_top_bg_color_hover'] = array(
      '#type' => 'color',
      '#title' => $this->t('Background color on mouse over.'),
      '#description' => $this->t('Button background color on mouse over default #777777'),
      '#default_value' => $config->get('bg_color_hover'),
      '#size' => 10,
      '#maxlength' => 7,
    );
    $form['scroll_to_top_bg_color_out'] = array(
      '#type' => 'color',
      '#title' => $this->t('Background color on mouse out.'),
      '#description' => $this->t('Button background color on mouse over default #CCCCCC'),
      '#default_value' => $config->get('bg_color_out'),
      '#size' => 10,
      '#maxlength' => 7,
    );
    $form['scroll_to_top_display_text'] = array(
      '#type' => 'checkbox',
      '#title' => $this->t('Display label'),
      '#description' => $this->t('Display "BACK TO TOP" text under the button'),
      '#default_value' => $config->get('display_text'),
    );
    $form['scroll_to_top_enable_admin_theme'] = array(
      '#type' => 'checkbox',
      '#title' => $this->t('Enable on administration theme.'),
      '#description' => $this->t('Enable scroll to top button on administartion theme.'),
      '#default_value' => $config->get('enable_admin_theme'),
    );
    $form['scroll_to_top_preview'] = array(
      '#type' => 'item',
      '#title' => $this->t('Preview'),
      '#markup' => '<div id="scroll-to-top-prev-container">' . t('Change a setting value to see a preview. "Position" and "enable on admin theme" not included.') . '</div>',
    );

    return parent::buildForm($form, $form_state);
  }

  /**
  * {@inheritdoc}
  */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $label = $form_state->getValue('scroll_to_top_label');
    $position = $form_state->getValue('scroll_to_top_position');
    $bg_color_hover = $form_state->getValue('scroll_to_top_bg_color_hover');
    $bg_color_out = $form_state->getValue('scroll_to_top_bg_color_out');
    $display_text = $form_state->getValue('scroll_to_top_display_text');
    $enable_admin_theme = $form_state->getValue('scroll_to_top_enable_admin_theme');

    // Get the config object.
    $config = $this->config('scroll_to_top.settings');

    // Set the values the user submitted in the form
    $config->set('label', $label)
        ->set('position', $position)
        ->set('bg_color_hover', $bg_color_hover)
        ->set('bg_color_out', $bg_color_out)
        ->set('display_text', $display_text)
        ->set('enable_admin_theme', $enable_admin_theme)
        ->save();
  }
}

We first define the namespace of our class and next extend our class from ConfigFormBase, which is a class with defined methods that we inherit in our class to manage the configuration values. We also use the class FormStateInterface in our buildForm and submitForm method through Dependency Injection.

The method getFormId() returns the id of the form.

Note that buildForm is almost a copy of what we had in the scroll_to_top.admin.inc but with little changes like $this->t() instead the global t(), we changed the button backgrounds in the inputs type textfield for color thanks to the new type of input in HTML5 that Drupal 8 uses now and we also accessed to the configuration through a configuration object ($config = $this->config('scroll_to_top.settings');) and replaced all variable_get() for $config->get(). As parameter in $config->get() we pass the name of the value in the configuration management.

Once the user click on Save configuration a validateForm() method can be called to validate inputs, but here we just use the submitForm method directly to save the settings value in the configuration management.

Note that we access to the inputs value through their ids that we specified as a key in the form array during the form was built. Next we set the values and we finally save the values calling the set method.

At this point we already have our configuration form running, in the next chapter we are going to see how to make our button works (that is the most important behavior of the module).

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s