Drupal 9 Course: Create a Config Page - Part 3 - [2021]

We want to create a very simple configuration page for our API module.

Step 1:

Let’s update our routing file and add a new route with the following:

movie_directory.api_config_page:
  path: '/admin/config/movie-api'
  defaults:
    _form: '\Drupal\movie_directory\Form\MovieAPI'
    _title: 'Movie API - Settings'
  requirements:
    _permission: 'administer site configuration'

Step 2:

Now let's create our form class that will serve our custom configuration page. Create a new director called "Form" in the "src" directory. Then in the form directory create a new file and name it `MovieAPI`. Note that this matches the class we added to our routing file.

Form directory

Step 3:

Open up the MovieAPI.php file and add the following:

<?php

namespace Drupal\movie_directory\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MovieAPI
 * @package Drupal\movie_directory\Form
 */
class MovieAPI extends FormBase {

  /**
   * Get config form configuration id.
   */
  const MOVIE_API_CONFIG_PAGE = 'movie_api_config_page:values';

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'movie_api_config_page';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

  }

}

You will notice that we have a constant. I must emphasise that a constant is NOT MANDATORY. I personally like using them to be a bit organised. I will explain why we will need it later on.

The `getFormId()` gives our form a custom form id. In Drupal, every form MUST have an ID.

 Next is `buildForm()`. This is where we create our form elements and return them. These elements will be rendered on our page (/admin/config/movie-api).

Step 4:

We will need two text fields. One field to store the api endpoint, and another text field to store the API Key.

So our buildForm will end up like this:

  public function buildForm(array $form, FormStateInterface $form_state) {
    $values = \Drupal::state()->get(self::MOVIE_API_CONFIG_PAGE);

    $form['api_base_url'] = [
      '#type' => 'textfield',
      '#title' => $this->t('API Base URL'),
      '#description' => $this->t('This is the API Base URL'),
      '#default_value' => ($values['api_base_url']) ?: 'https://api.themoviedb.org/3',
      '#required' => TRUE,
    ];

    $form['api_key'] = [
      '#type' => 'textfield',
      '#title' => $this->t('API Key (v3 auth)'),
      '#description' => $this->t('This can be obtained from https://www.themoviedb.org/settings/api. You must have an account with themoviedb.'),
      '#default_value' => $values['api_key'],
      '#required' => TRUE,
    ];

    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

Let's break down what's happening here.

The $values variable is used to get the previously stored values using Drupal's states. Depending on the requirements, we could use a ConfigForm. But personally speaking, I prefer using states because this allows for easy change without having to accidentally lose the details on the next deployment to production.

Next, we have our form elements, as you can see both elements have '#type' that is 'textfield'.

Then we have our actions which triggers a submission of the form.

Now clear caches and go to our new page "/admin/config/movie-api" and you should see something like this.

api config page

Step 5:

We need to add the `submitForm` method which is triggered once we click the "Save" button.

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $submitted_values = $form_state->cleanValues()->getValues();

    \Drupal::state()->set(self::MOVIE_API_CONFIG_PAGE, $submitted_values);

    $messenger = \Drupal::service('messenger');
    $messenger->addMessage($this->t('Your new configuration has been saved.'));
  }

This method allows us to store/save the data used in our form.

$submitted_values (self explanatory) contains the values submitted....

We then use Drupal states to save our values. Notice the first parameter in the set method of States is the "state id". This will be the constant we created earlier, and the second parameter is our values from the form.

Step 6:

So now enter random values and try to save the page.

If you can see the values you entered after saving the page, then your configuration form works!

I will show you how to get the correct movie api details in the next tutorial.