Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The settings form

A settings form is a page in the panel where the administrator changes the module configuration. There is a ready base class for it, ConfigFormBase: it adds the "Save configuration" button and the success message. All that is left is to describe the fields and write the values.

Where the form lives

Like an ordinary form — in the src/Form folder of the module. Create the file by hand.

The form class

// web/modules/custom/blog/src/Form/SettingsForm.php
namespace Drupal\blog\Form;
 
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
 
class SettingsForm extends ConfigFormBase
{
    public function getFormId(): string
    {
        return 'blog_settings_form';
    }
 
    protected function getEditableConfigNames(): array
    {
        return ['blog.settings'];
    }
 
    public function buildForm(array $form, FormStateInterface $form_state): array
    {
        $form['list_title'] = [
            '#type' => 'textfield',
            '#title' => $this->t('List title'),
            '#default_value' => $this->config('blog.settings')->get('list_title'),
        ];
 
        return parent::buildForm($form, $form_state);
    }
 
    public function submitForm(array &$form, FormStateInterface $form_state): void
    {
        $this->config('blog.settings')
            ->set('list_title', $form_state->getValue('list_title'))
            ->save();
 
        parent::submitForm($form, $form_state);
    }
}

There are three differences from an ordinary form. The getEditableConfigNames() method names the configuration objects the form changes — thanks to it $this->config() returns a writable object here. #default_value puts the current value into the field. And the calls to parent::buildForm() and parent::submitForm() add the button and the message.

The route

Panel pages start with /admin. Settings pages are placed inside /admin/config:

# web/modules/custom/blog/blog.routing.yml
blog.settings:
  path: '/admin/config/content/blog'
  defaults:
    _form: '\Drupal\blog\Form\SettingsForm'
    _title: 'Blog settings'
  requirements:
    _permission: 'administer site configuration'

The administrator has the administer site configuration permission. After drush cr open /admin/config/content/blog, change the title and save — the /blog page from the previous lesson shows the new text.

To make the page easy to find, add a link to blog.links.menu.yml:

# web/modules/custom/blog/blog.links.menu.yml
blog.settings:
  title: 'Blog settings'
  description: 'The list title and the number of articles per page.'
  route_name: blog.settings
  parent: system.admin_config_content

The link appears on the Configuration page in the Content authoring group.

The button in the list of modules

# web/modules/custom/blog/blog.info.yml
configure: blog.settings

The line is added to the module description file. After drush cr the Extend page shows a Configure link next to the Blog module.

Several fields

Other settings are added the same way — a field in buildForm() and a line in submitForm():

// web/modules/custom/blog/src/Form/SettingsForm.php
$form['items_per_page'] = [
    '#type' => 'number',
    '#title' => $this->t('Articles per page'),
    '#default_value' => $this->config('blog.settings')->get('items_per_page'),
    '#min' => 1,
    '#max' => 50,
];
// web/modules/custom/blog/src/Form/SettingsForm.php
$this->config('blog.settings')
    ->set('list_title', $form_state->getValue('list_title'))
    ->set('items_per_page', (int) $form_state->getValue('items_per_page'))
    ->save();

A value from the form arrives as a string, while the schema declares the field as integer, so it is cast to a number.

Common mistake

Every value the form saves must be described in the schema config/schema/blog.schema.yml from the previous lesson. Without it Drupal reports a missing schema, and the value may be saved with the wrong type. When you add a field to the form, add it to the schema and to config/install/blog.settings.yml, then run drush cr.

Thanks for reading!

Donate to the site — we work hard for you.