Skip to main content

Extending the functionality of a contrib module in Drupal can enhance its usefulness without altering the original codebase. This article provides a step-by-step guide on how to add custom configuration options to an existing contrib module, using the sitewide_alert module as an example. We will extend its configuration by adding new settings through a separate custom module named sitewide_alert_ext.

Prerequisites

  • Drupal 10 installation
  • sitewide_alert contrib module installed and enabled
  • Basic knowledge of Drupal module development

 

Steps

Step 1: Create Your Custom Module

First, you need to create a new custom module. In your Drupal installation, navigate to the /web/modules/custom/ directory.  Create a folder named sitewide_alert_ext.  Within this folder, create the following files:

sitewide_alert_ext.info.yml

name: 'Extended Sitewide Alert Configuration'
type: module
description: 'Extends the Sitewide Alert configuration with additional settings.'
package: Custom
core_version_requirement: ^10
dependencies:
 - drupal:sitewide_alert

 

sitewide_alert_ext.permissions.yml

'administer sitewide alert settings extension':
 title: 'Administer extended sitewide alert settings'

 

Step 2: Define the Configuration Form

Create a new PHP class to handle the form by adding a new folder called src/Form within your module directory and creating a file named ExtendedSitewideAlertConfigForm.php:

<?php

namespace Drupal\sitewide_alert_ext\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class ExtendedSitewideAlertConfigForm extends FormBase {

  /**
   * The messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The configuration factory service, used for retrieving and storing configuration.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructor for the ExtendedSitewideAlertConfigForm.
   *
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service for showing notifications.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The config factory for handling configurations.
   */
  public function __construct(MessengerInterface $messenger, ConfigFactoryInterface $configFactory) {
    $this->messenger = $messenger;
    $this->configFactory = $configFactory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('messenger'),
      $container->get('config.factory')
    );
  }

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

  /**
   * Builds the form for sitewide alert extension settings.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The form structure.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->configFactory->get('sitewide_alert_ext.settings');

    $form['max_alerts'] = [
      '#type' => 'select',
      '#title' => $this->t('Maximum number of alerts displayed'),
      '#options' => range(1, 5),
      '#default_value' => $config->get('max_alerts'),
    ];

    $form['alert_title'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Alert title'),
      '#default_value' => $config->get('alert_title'),
    ];

    $form['alert_message'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Alert message when more than maximum alerts'),
      '#default_value' => $config->get('alert_message'),
    ];

    $form['alert_color'] = [
      '#type' => 'color',
      '#title' => $this->t('Alert colour'),
      '#default_value' => $config->get('alert_color'),
    ];

    // Submit button for saving the configuration.
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save configuration'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

  /**
   * Handles form submissions; saves the new configuration values.
   *
   * @param array &$form
   *   The form render array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Save the configuration using the values provided in the form.
    $this->configFactory->getEditable('sitewide_alert_ext.settings')
        ->set('max_alerts', $form_state->getValue('max_alerts'))
        ->set('alert_title', $form_state->getValue('alert_title'))
        ->set('alert_message', $form_state->getValue('alert_message'))
        ->set('alert_color', $form_state->getValue('alert_color'))
        ->save();

    // Inform the user that settings have been successfully saved.
    $this->messenger->addMessage($this->t('Your settings have been saved.'));
  }
}

 

Step 3: Define Routing and Menu Links

In your module folder, create sitewide_alert_ext.routing.yml:

entity.sitewide_alert.config_form.extension:
 path: '/admin/config/sitewide_alerts/extension'
 defaults:
   _form: '\Drupal\sitewide_alert_ext\Form\ExtendedSitewideAlertConfigForm'
   _title: 'Extended Sitewide Alert Settings'
 requirements:
   _permission: 'administer sitewide alert settings extension'
 options:
   _admin_route: TRUE

 

And sitewide_alert_ext.links.task.yml for the tab:

entity.sitewide_alert.config_form.extension:
 route_name: entity.sitewide_alert.config_form.extension
 title: 'Extension'
 base_route: entity.sitewide_alert.config_form
 weight: 10

 

Step 4: Enable the Module and Clear Cache

Use Drush or the Drupal admin UI to enable the sitewide_alert_ext module:

drush en sitewide_alert_ext

 

Clear the cache to make sure your changes are applied:

drush cr

 

Step 5: Test the New Configuration

Navigate to the Sitewide Alert settings in the admin panel. You should see a new tab labeled "Extension" alongside the original settings tab. This new tab will contain the fields you added.

 

Conclusion

Extending a contrib module's functionality using a custom module allows you to tailor the functionality to meet specific needs without hacking the original module, facilitating easier updates and maintenance. This example demonstrates how Drupal's modular architecture encourages flexible enhancements while maintaining system integrity.

Related articles

Andrew Fletcher30 Apr 2024
Best Practices for Configuring Twig Debug Settings in Drupal 10
When developing with Drupal 10, it's crucial to maintain an environment that is both secure and efficient. One of the important aspects of this setup involves the management of Twig template debugging. Proper configuration of these settings helps prevent unnecessary performance degradation and...