Codementor Events

How to extend an existing Drupal 8+ Form

Published Jul 28, 2023
How to extend an existing Drupal 8+ Form

The Drupal FOSS CMS (Free and Open Source Software Content Management System) is considered to be the one of the most developer friendly CMS available. However, for those new to Drupal, something as "simple" as changing the text displayed after submitting a form can be daunting. Originally released in 2011, with Drupal 7, the Drupal Entity API defines different types of information stored and displayed in Drupal. When Drupal 8 was released, the concept was further refined into what's referred to as "specifically typed objects", meaning that each Entity is defined as having a specific set of information and operations that can be performed on it. As you might imagine, Drupal 8 Forms are used to perform operations on Entities, such as add, edit, and delete. When creating a form, a form handler is used to define which class should be used. So, when you want to modify the implementation of a form, you will need to extend the original form's class and tell the system to use your custom class. Simple, right? Let's step through the process...

The Use Case

In order to best illustrate the process of extending and existing Drupal 8 Form, we will modify the submit messages for the Simplenews subscribe form.

Setup Your Dev Environment

When creating new functionality for your Drupal website, it is always best to use a local development environment. We recommend using Docksal with Docker to accomplish this task because it is simple to setup and includes essential tools for developing with Drupal. We are also going to make sure the contrib module we are modifying is installed and enabled.

  1. Goto Docksal.io and follow install instructions for your Operating System on the OS Support tab to install Docksal with Docker
  2. Open Terminal/Console
  3. Create projects directory: mkdir ~/Sites
  4. Create project with Docksal: fin project create
  5. Name your project & Choose Drupal 8 when prompted (Composer Version is recommended)
    lYQFExy.jpg
    extendform
  6. Enter y to proceed with setup
    BN8BAG3.jpg
  7. Verify you able to access the website using the URL and credentials provided when the install is complete
    Lx6aFXB.jpg
  8. Change to your project's directory: cd ~/Sites/{project_name}
    mEmITln.jpg
  9. If the original form is provided by a contributed module, install it: fin composer require 'drupal/{contrib_project}:^{version}'
    nPXgsvP.jpgp

and enable it: fin drush en {contrib_project}
bbnEinH.jpg

Generate Your Custom Module

Now that your local environment is setup, you will need to generate your custom module that will provide the code that will extend the existing form you are modifying. We recommend using Drupal Console to accomplish this task. No need to install Drupal Console because it comes pre-installed with Docksal!

  1. Generate Module: fin drupal generate:module
    NOTE: Do not generate a composer.json file now because it will produce an error
    SlePwTS.jpg

and Enter/yes when prompted
hF7n6EP.jpg

  1. Generate Composer File: fin drupal generate:composer
    WeQXauR.jpg

and Enter/yes when prompted
XNs0HAH.jpg

Locate the Existing Form Code

In this scenario, we are wanting to change the message that displays after subscribing to a newsletter provided by the Simplenews module. Let's look for the original code that generates that message.

  1. Search Files for message: grep -rl "{message}" .
    CRnrAuZ.jpg
  2. Open Project in your favorite file editor. Ex: bbedit .
    Navigate to file from search in Step 1
    OfAaaWK.jpg
  3. Locate message in file to verify function that needs to be customized. CTRL(Win)/Command(Mac)+F
    2DN2F8I.jpg

Copy and Rename the Form File

The easiest way to limit the number of mistakes is to copy the existing files from the original location into your custom module.

  1. Prepare Destination Folder: mkdir -p web/modules/custom/{custom_module}/src/Form
    S4R1cXG.jpg
  2. Copy Files: cp web/modules/contrib/simplenews/src/Form/SubscriptionsBlockForm.php web/modules/custom/{custom_module}/src/Form/
    NHlu2Gd.jpg
  3. Rename Files (so unique): mv web/modules/custom/customize_simplenews_sub_form/src/Form/SubscriptionsBlockForm.php web/modules/custom/{custom_module}/src/Form/SubscriptionsCustomBlockForm.php
    mfdpZ8t.jpg
  4. Repeat Steps 2 & 3 for all applicable files in Step 1. NOTE: In this scenario, we did not need to change the file in the Tests directory.

Customize the Form Code

Now we need to modify the Code so that it extends the existing code.

  1. Alter namespace to your Custom module: namespace Drupal\{custom_module}\Form;
    bG8xCR3.jpg
  2. Add use statement for original code with alias that is same as what was extended in Original Code: use Drupal\simplenews\Form\SubscriptionsBlockForm as SubscriptionsFormBase;
    SI5pkv6.jpg
  3. Customize Class name to make unique for your module: SubscriptionsCustomBlockForm
    xKqyQPJ.jpg
  4. Remove all code in file, except function located in Step 4 of the Locate the Existing Form Code: getSubmitMessage()
    Before editing code:
    VCWczP5.jpg
    After removing extra code:
    mAOgcRi.jpg
  5. Alter code, as needed. Ex: line 19: return $this->t('This is a different update message.');
    W4MxlbT.jpg

Set the Form Handler Class

Almost done coding! Just need to edit the Handler Class for the entity we are modifying.

  1. Add hook to alter entity: function customize_simplenews_sub_form_entity_type_alter(array &$entity_types)
  2. Edit handler class for entity: @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[]
    ucz34T9.jpg

Enable Your Custom Module

Congrats! The coding is over! Now, just enable the module, refresh and test to verify.

  1. Verify system sees module: fin drush pml | grep {custom_module}
    C17k2WL.jpg
  2. Enable the Custom Module: fin drush en {custom_module}
    cbwUntZ.jpg
  3. If warning encountered during enable:
    [warning] Invalid json in modules/custom/customize_simplenews_sub_form/composer.json
    a. Disable the Custom Module: fin drush pmu {custom_module}
    ePubB8J.jpg
    b. Open the custom modules composer.json file: bbedit ~/Sites/{custom_module}/composer.json
    lfwB6KC.jpg
    c. Remove extra comma in require section & Save changes.
    CQzNL8F.jpg
    d. Enable the Custom Module: fin drush en {custom_module}
    cbwUntZ.jpg
  4. Revisit Subscription Page Verify Changes. NOTE: If this is a fresh install, you may need to add the simplenews block to the sidebar.

Congrats!

You have successfully extended and existing form programmatically the "Drupal way". Hopefully, this introduction to extending Drupal code has provided you with a simple use case that will help you to continue extending other code. If you ever get stuck, please don't hesitate to contact me to sign-up for a mentoring session.

Discover and read more posts from Norah Medlin
get started