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'); } }
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 withDemo 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 toworld.
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; }
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']); }
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'); } }
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; }
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']); }
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'); } }
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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











There are four main error types in PHP: 1.Notice: the slightest, will not interrupt the program, such as accessing undefined variables; 2. Warning: serious than Notice, will not terminate the program, such as containing no files; 3. FatalError: the most serious, will terminate the program, such as calling no function; 4. ParseError: syntax error, will prevent the program from being executed, such as forgetting to add the end tag.

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

In PHP, password_hash and password_verify functions should be used to implement secure password hashing, and MD5 or SHA1 should not be used. 1) password_hash generates a hash containing salt values to enhance security. 2) Password_verify verify password and ensure security by comparing hash values. 3) MD5 and SHA1 are vulnerable and lack salt values, and are not suitable for modern password security.

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

HTTP request methods include GET, POST, PUT and DELETE, which are used to obtain, submit, update and delete resources respectively. 1. The GET method is used to obtain resources and is suitable for read operations. 2. The POST method is used to submit data and is often used to create new resources. 3. The PUT method is used to update resources and is suitable for complete updates. 4. The DELETE method is used to delete resources and is suitable for deletion operations.

In PHPOOP, self:: refers to the current class, parent:: refers to the parent class, static:: is used for late static binding. 1.self:: is used for static method and constant calls, but does not support late static binding. 2.parent:: is used for subclasses to call parent class methods, and private methods cannot be accessed. 3.static:: supports late static binding, suitable for inheritance and polymorphism, but may affect the readability of the code.

PHP handles file uploads through the $\_FILES variable. The methods to ensure security include: 1. Check upload errors, 2. Verify file type and size, 3. Prevent file overwriting, 4. Move files to a permanent storage location.
