Table of Contents
What is the basic structure of Drupal 8 module?
How to create custom blocks in Drupal 8?
How to create a custom form in Drupal 8?
How to display blocks in specific areas of my Drupal 8 site?
How to verify input of Drupal 8 custom form?
How to change an existing form in Drupal 8?
How to programmatically submit a form in Drupal 8?
How to create a configuration form in Drupal 8?
How to create a multi-step form in Drupal 8?
How to create an AJAX form in Drupal 8?
Home Backend Development PHP Tutorial Building a Drupal 8 Module: Blocks and Forms

Building a Drupal 8 Module: Blocks and Forms

Feb 21, 2025 am 08:45 AM

Building a Drupal 8 Module: Blocks and Forms

Core points

  • Drupal 8 introduces a new concept of blocks as a plugin, allowing them to be reused throughout the site. Blocks can be created in the UI and used multiple times.
  • In Drupal 8, you can create a custom block that returns configurable text. This can be done by creating a new block type in the UI and reusing it throughout the site.
  • Drupal 8 allows adding configuration forms to blocks. This enables the user to edit the block, specify a name in the text field, and the block will then display a greeting to that name.
  • Drupal 8 module development involves creating a simple form. Form definition functions are grouped together in a class. Submitted form values ​​are simply printed on the screen to show how they work.
  • In Drupal 8, you can create custom forms by defining form classes in custom modules. The form class should extend the "FormBase" class and implement three methods: "getFormId()", "buildForm()", and "submitForm()".

Note that some code parts may be outdated due to the ongoing development process of Drupal 8 at the time of writing. Please check out this repository, I tried updating the sample code and making it work with the latest Drupal 8 version.

In the first part of this series, we start with the basics and learn Drupal 8 module development. We've learned how Drupal understands the files required by our module, how the routing process works, and how to create menu links programmatically in a configuration manner.

In this tutorial, we will further look at the sandbox modules found in this repository and look at two important features: blocks and forms. To do this, we will create a custom block that returns some configurable text. After that, we will create a simple form for printing the user-submitted values ​​to the screen.

Drupal 8 Block

A cool new change to the Block API in D8 is to make blocks more prominent by making them as plugins (a whole new concept). This means they are reusable features (in the background), as you can now create a block in the UI and reuse it throughout the site – you are no longer limited to using blocks only once.

Let's create a simple block type that will print to the screen by default Hello World!. We only need to use a class file in the src/Plugin/Block folder located in the root of the module. Let's name our new block type DemoBlock, of course it needs to be in a file named DemoBlock.php. In this file we can start with the following:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
Copy after login
Copy after login
Copy after login

Like all other class files, we first namespace our class. Then we use the BlockBase class so that we can extend it, and the AccountInterface class so that we can access the currently logged in user. Next is something you certainly haven't seen in Drupal 7: Comments.

Annotations are PHP discovery tools located in comment blocks in files that are the same as class definitions. Using these annotations, we let Drupal know that we want to register a new block type (@Block) with the ID demo_block and the admin_label with

Demo block (passed through the translation system).

Next, we extend the BlockBase class to our own DemoBlock, where we implement two methods (the most common methods you will implement). The build() method is most important because it returns the renderable array that the block will print out. The access() method controls access to view this block. The argument passed to it is an instance of the AccountInterface class, in which case it is the current user.

Another interesting thing to note is that we no longer use the t() function globally for translation, but instead refer to the t() method implemented in the class parent class.

That's it, you can clear the cache and go to the Block Layout configuration page. The cool thing is that you have block types on the right (you can filter through them) where you can place one or more of these types of blocks into various areas of the site.

Drupal 8 Block Configuration

Now that we have learned how to create a new block type to use in the UI, let's dig deeper into the API and add configuration forms to it. We will enable it to edit the block, specify a name in the text field, and the block will say hello to that name, rather than to say hello to

world.

First, we need to define a form containing our text fields. So, in our DemoBlock class, we can add a new method called blockForm():

/**
 * {@inheritdoc}
 */
public function blockForm($form, &$form_state) {

  $form = parent::blockForm($form, $form_state);

  $config = $this->getConfiguration();

  $form['demo_block_settings'] = array(
    '#type' => 'textfield',
    '#title' => $this->t('Who'),
    '#description' => $this->t('Who do you want to say hello to?'),
    '#default_value' => isset($config['demo_block_settings']) ? $config['demo_block_settings'] : '',
  );

  return $form;
}
Copy after login
Copy after login
This form API implementation should look very similar to Drupal 7. However, there is some new content here. First, we retrieve the $form array from the parent class (so we build an existing form by adding our own fields). Standard OOP stuff. We then retrieve and store the configuration of this block. The BlockBase class defines the getConfiguration() method that does this for us. We place the demo_block_settings value as #default_value in case it has been set.

Next, is the submission handler for this form, which will process the value of our field and store it in the chunk's configuration:

/**
* {@inheritdoc}
*/
public function blockSubmit($form, &$form_state) {

 $this->setConfigurationValue('demo_block_settings', $form_state['values']['demo_block_settings']);

}
Copy after login
Copy after login
This method is also located in the DemoBlock class, and all it does is save the value of the demo_block_settings field as a new item in the block configuration (using the same name as the key for consistency).

Finally, we need to adjust our build() method to include the name to ask:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
Copy after login
Copy after login
Copy after login

So far, this should look pretty easy. We are searching for the configuration of the block and use it for the printed statement if the value of our field has been set. If not, a common statement is used. You can clear the cache and test it by editing the blocks you assigned to the zone and adding the name you want to ask for. One thing to note is that you still have the responsibility to clean up user input when printing to the screen. For brevity, I did not include these steps.

Drupal 8 Form

The last thing we're going to explore in this tutorial is how to create a simple form. Due to space limitations, I will not cover its configuration management aspect (stores configuration values ​​submitted through forms). Instead, I'll illustrate a simple form definition where the submitted value is simply printed on the screen to show how it works.

In Drupal 8, form definition functions are grouped in a class. So let's define our simple DemoForm class in src/Form/DemoForm.php:

/**
 * {@inheritdoc}
 */
public function blockForm($form, &$form_state) {

  $form = parent::blockForm($form, $form_state);

  $config = $this->getConfiguration();

  $form['demo_block_settings'] = array(
    '#type' => 'textfield',
    '#title' => $this->t('Who'),
    '#description' => $this->t('Who do you want to say hello to?'),
    '#default_value' => isset($config['demo_block_settings']) ? $config['demo_block_settings'] : '',
  );

  return $form;
}
Copy after login
Copy after login

Apart from the OOP aspect, everything should be very similar to Drupal 7. The Form API has hardly changed (except for adding some new form elements and such encapsulation). So what happened above?

First, we namespace the class and use the core FormBase class so that we can extend it with our own DemoForm class. Then we implement 4 methods, 3 of which should look very familiar. The getFormId() method is new and mandatory and is only used to return the machine name of the form. The buildForm() method is again mandatory, which builds the form. how? Just like you're used to from Drupal 7. The validateForm() method is optional and its purpose should also be very clear from D7. Finally, the submitForm() method performs the commit processing. Very logical and organized.

So what do we want to achieve with this form? We have an email field (a new form element in Drupal 8) that we want the user to fill in. By default, Drupal checks whether the entered value is actually an email address. But in our verification function we make sure it is a .com email address and if it is not, we will set the form error on that field. Finally, the submission handler simply prints a message on the page.

The last thing we need to do in order to use this form is to provide it with a route. So edit the demo.routing.yml file and add the following:

/**
* {@inheritdoc}
*/
public function blockSubmit($form, &$form_state) {

 $this->setConfigurationValue('demo_block_settings', $form_state['values']['demo_block_settings']);

}
Copy after login
Copy after login

This should be similar to what we routed simple pages in the previous post. The only significant difference is that under defaults, we use _form to specify that the target is the form class. Therefore, the value is the class name we just created.

Clear the cache and navigate to demo/form to view the form and test it.

If you are familiar with drupal_get_form() and want to know how to load forms like you did in Drupal 7 before, the answer is in the global Drupal class. So to retrieve a form, you can use its formBuilder() method and do the following:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
Copy after login
Copy after login
Copy after login

You can then return $form, which will be a renderable array of the form.

Conclusion

In this article, we continue to explore Drupal 8 module development and introduce two new topics: blocks and forms. We have learned how to create our own block type, which we can use to create blocks in the UI. We also learned how to add custom configurations to it and store values ​​for later use. Regarding forms, we have seen a simple implementation of the FormBase class, which we use to print the user-submitted values ​​to the screen.

In the next tutorial, we will quickly learn about the configuration form. We will use the Drupal 8 configuration system to save user-submitted values. Additionally, we will learn about service containers and dependency injections and how they work in Drupal 8. See you then.

Frequently Asked Questions about Building Drupal 8 Modules: Blocks and Forms (FAQ)

What is the basic structure of Drupal 8 module?

The Drupal 8 module is essentially a set of files containing certain functions and is written in PHP. The basic structure of the Drupal 8 module includes .info.yml file, .module file, and other optional files, such as .css, .js, .twig, etc. The .info.yml file is used to list the module's name, description, package, type, and core compatibility. The .module file is where the actual PHP code is located.

How to create custom blocks in Drupal 8?

Creating a custom block in Drupal 8 involves creating a new custom module and defining a block plugin in it. The block plugin is a PHP class file that defines the properties and methods of the block. It should be placed in the "src/Plugin/Block" directory of the module. The block plugin class should extend the "BlockBase" class and implement the "build()" method, which returns a renderable array of block content.

How to create a custom form in Drupal 8?

Creating a custom form in Drupal 8 involves creating a new custom module and defining a form class there. The form class is a PHP class file that defines the properties and methods of the form. It should be placed in the "src/Form" directory of the module. The form class should extend the "FormBase" class and implement three methods: "getFormId()", "buildForm()", and "submitForm()". The "buildForm()" method returns the form array, and the "submitForm()" method handles the form submission.

How to display blocks in specific areas of my Drupal 8 site?

To display blocks in a specific area of ​​the Drupal 8 site, you need to go to the Block Layout page in the management interface. Here you can assign your block to any area of ​​the topic. You can also configure the visibility settings of blocks based on paths, content types, user roles, etc.

How to verify input of Drupal 8 custom form?

To verify input to a Drupal 8 custom form, you can override the "validateForm()" method in the form class. When submitting the form, this method is called before the "submitForm()" method. In the "validateForm()" method, you can add validation logic and call the "setError()" method to set the error message for the form element (if validation fails).

How to change an existing form in Drupal 8?

To change an existing form in Drupal 8, you can implement the "hook_form_FORM_ID_alter()" function in the module. This function is called when building a form, which allows you to modify the form array. "FORM_ID" should be replaced with the ID of the form you want to change.

How to programmatically submit a form in Drupal 8?

To programmatically submit a form in Drupal 8, you can create an instance of the form class and call the "submitForm()" method on it. However, before calling this method, you should prepare a form state object and set the value of the form element in it.

How to create a configuration form in Drupal 8?

To create a configuration form in Drupal 8, you can define a form class that extends the "ConfigFormBase" class instead of the "FormBase" class. The "ConfigFormBase" class provides other methods for processing configuration data, such as "getEditableConfigNames()" and "config()". Configuration data is stored in the Drupal configuration system and can be accessed from anywhere in the code.

How to create a multi-step form in Drupal 8?

To create a multi-step form in Drupal 8, you can use the FormStateInterface object to store data between steps. In the "buildForm()" method, you can check the current step in the form state and return a different form array for each step. In the "submitForm()" method, you can check the current step, then store the data and go to the next step, or process the final commit.

How to create an AJAX form in Drupal 8?

To create an AJAX form in Drupal 8, you can add the "#ajax" attribute to the form element in the "buildForm()" method. This property should be an array that specifies the callback function to be called when the element is triggered. The callback function should return a portion of the form to be updated or a set of AJAX commands.

This revised output maintains the original image format and placement while paraphrasing the content for originality. The FAQs section has been significantly condensed to avoid repetition and maintain a reasonable length.

The above is the detailed content of Building a Drupal 8 Module: Blocks and Forms. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

What are Enumerations (Enums) in PHP 8.1? What are Enumerations (Enums) in PHP 8.1? Apr 03, 2025 am 12:05 AM

The enumeration function in PHP8.1 enhances the clarity and type safety of the code by defining named constants. 1) Enumerations can be integers, strings or objects, improving code readability and type safety. 2) Enumeration is based on class and supports object-oriented features such as traversal and reflection. 3) Enumeration can be used for comparison and assignment to ensure type safety. 4) Enumeration supports adding methods to implement complex logic. 5) Strict type checking and error handling can avoid common errors. 6) Enumeration reduces magic value and improves maintainability, but pay attention to performance optimization.

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

How to send a POST request containing JSON data using PHP's cURL library? How to send a POST request containing JSON data using PHP's cURL library? Apr 01, 2025 pm 03:12 PM

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

See all articles