Adding the new vendor attendance feature starts with adding a custom module, and defining the form controller with a simplified user interface. This is mostly accomplished using concepts that we've already explored, so we'll use this as a chance to practice what we've learned.
In this tutorial, we'll:
- Construct a new module, form controller, and route.
- Discover how to create local tasks for an enhanced administrative UI.
By the end of this tutorial you should be able to navigate to the Attendance tab of Vendor node to access a simplified UI.
We need a place to put the custom PHP code for our /weather page. In Drupal, controllers encapsulate the custom PHP logic that generates the content of a page. A basic controller might output a hard-coded response, or perform a simple calculation in PHP. Complex controllers make database requests, query third-party APIs, and format complex data using injected services and custom PHP logic.
In this tutorial, we'll:
- Create a new controller class following the PSR-4 standard.
- Define the
Drupal\anytown\Controller\WeatherPage
class with abuild()
method that returns the page's content. - Verify that our route and controller are working.
By the end of this tutorial, you should be able to navigate to /weather in your browser and see the output from our custom controller.
Drupal allows site administrators to configure view modes, defining an entity's display. As module developers, we use view builders to transform an entity object into a renderable array, respecting site-specific configurations without hard-coding display details.
In this tutorial, we'll:
- Introduce view builders and explain their significance in entity rendering.
- Develop a route and controller for a new /attending page
- Use an entity query to retrieve vendor nodes and render them with view builders
By the end of this tutorial, you'll know how to display entities using a site-specific teaser view mode.
In Drupal, content entities can have fields. Field data is entered using widgets and displayed with formatters. The Field API provides developers with means to customize fields, widgets, and formatters. Which gives site builders tools to build flexible, extensible sites using customized data models.
In this tutorial, we'll:
- Learn what it means for an entity to be fieldable.
- Define what field types, widgets, and formatters are and give examples of each.
- Explore the differences between base fields and user-defined fields.
- Define the concept of field instances.
By the end of this tutorial you should be able to define the main components of the Field API and understand how developers leverage the Field API to alter and enhance Drupal.
Entity objects are loaded using the entity type manager service (technically, the entity storage manager). Field values are read from the entity object. Doing this, instead of directly accessing data in the database, ensures that our custom code can remain agnostic about any underlying data storage logic. Reading field values is a common task, and we'll practice it by loading a vendor entity and using existing field values to pre-populate the new vendor attendance form.
In this tutorial, we'll:
- Load an entity using the entity type manager service.
- Access raw values of entity fields.
- Use
#default_value
in Form API to pre-populate form fields.
By the end of this tutorial, you'll be able to get raw field values from entities.
Implementing plugins is a common task for Drupal developers. Often you'll need to add custom functionality using an existing plugin type--most likely an annotation-based plugin. This tutorial offers a structured approach to understanding and creating Drupal plugins, with a focus on annotation-based plugins.
In this tutorial, we'll:
- Examine the custom block code we previously wrote, this time from the perspective of the Plugin API.
- Introduce a recipe for creating annotation-based Drupal plugins.
- Demonstrate how to find the necessary information for new plugin creation from existing plugins.
By the end of this tutorial, you will know how to examine the structure of existing plugin classes, so that you know how to implement a plugin of that type.
Let's combine our knowledge of implementing hooks and hook_form_alter()
to customize a form built by another module, the user registration form. For the Anytown Farmer's Market site's user registration form, we want to introduce 2 new features: a mandatory "Accept terms of use" checkbox and custom validation to prevent registration with the username "anytown".
In this tutorial, we'll:
- Identify the form ID of the user registration form.
- Incorporate new elements into the user registration form.
- Implement additional validation logic.
By the end of this tutorial, you should be able to use hook_form_alter()
to customize any existing Drupal form.
Drupal uses 4 primary information types for canonical data storage: content, configuration, session, and state. Content encompasses the site's visible data, such as articles, images, and files. Content data are called content entities in Drupal. Configuration data stores site settings including site name, content types, and views. Session data tracks user interactions, including login status. State data holds temporary information like the last cron execution time.
In this tutorial, we'll:
- Define the 4 main information types and their use cases.
- Get a high-level overview of when module developers should expect to encounter each data type.
By the end of this tutorial you should be able to recognize each of the 4 main information types used in Drupal.
Plugins enable developers to extend and customize functionality through a modular and reusable system. Plugins allow for the creation of interchangeable components that can be managed dynamically at runtime. This tutorial introduces the core concepts of Drupal's Plugin API, including how plugins, such as blocks, are defined, discovered, and used within the system.
In this tutorial, we'll:
- Define plugins in Drupal's context.
- Explain the Plugin system's operation, including types, managers, discovery, and factories.
- Discuss the role of plugins in extending Drupal.
By the end of this tutorial, you should have a high-level understanding of plugins and the Plugin API in Drupal.
Drupal's Entity API enables us to define custom content entity types. It provides a structured approach to store custom data. Creating a custom entity makes sense when built-in entity types like nodes or taxonomy terms don't meet the specific requirements of a project. Custom entities allow for custom data structures, and use Drupal's core features such as access control, Views integration, and JSON:API support. Using the Entity API to create custom content entities ensures your custom data will be compatible with other Drupal modules.
In this tutorial, we'll:
- Discuss use cases for custom content entities.
- Get a high-level overview of defining a custom entity type.
- Provide additional resources where you can learn more about defining custom entity types.
By the end of this tutorial, you'll understand the use case for custom content entities and how to begin defining one.
To implement a custom vendor attendance status feature, we need to add new fields to the Vendor content type. This tutorial will guide you through adding these fields and discuss the considerations for choosing between Drupal's UI for data modeling versus code-based alterations of entity types.
In this tutorial, we'll:
- Add new fields to the Vendor content type required for the vendor attendance status feature.
- Discuss the pros and cons of modeling data with Drupal's Field UI compared to using hooks for modifying entity base fields.
By the end of this tutorial, you'll know how to update the Vendor content type with necessary fields and understand why this approach suits our specific case.
This guide was written, and is maintained, by Drupalize.Me. For more high quality written and video Drupal tutorials created by our team of experts, check out the collection of Drupalize.Me Guides.
Drupal's Form API (FAPI) is a comprehensive framework for managing forms within Drupal. The Form API extends the Render API, providing a structured approach to form creation, validation, and submission. It offers an abstraction layer over HTML forms and HTTP form handling, simplifying the process of capturing and processing user input securely and efficiently. Forms are integral to content management systems like Drupal, enabling user interactions ranging from content creation to configuration settings. For module developers, using the Form API is essential for building interactive and dynamic websites.
In this tutorial, we'll:
- Discuss the relationship between the Form API and the Render API.
- Highlight the significance of forms in Drupal and the role of the Form API in managing them.
- Outline the life cycle of a Drupal form, from definition to processing, including the role of form controllers.
By the end of this tutorial, you should grasp the fundamentals of the Form API and be prepared to construct and manage forms in Drupal modules.
One of the most powerful features of Drupal's Form API is the ability to alter nearly any aspect of the build, validate, or submit workflow in your custom code. Implementing hook_form_alter
is a common task for Drupal module developers, allowing them to modify forms to customize administrative or user-facing interfaces.
In this tutorial, we'll:
- Explore the purpose and use case for
hook_form_alter
and related hooks. - Learn how to target specific forms.
- Discover how to identify the form you wish to alter.
By the end of this tutorial, you should be able to select and implement the appropriate form alter hook to modify any form in Drupal.
Drupal's Menu system allows module developers to define navigational links, offering flexibility to site builders for configuration and arrangement. By linking to routes rather than URLs, these links remain functional, even when route definitions change.
In this tutorial, we'll:
- Create a MODULE_NAME.links.menu.yml file.
- Define a new menu item link for the /weather page in our anytown module.
- Configure Drupal to display the link in the primary navigation.
By the end of this tutorial, you'll be able to define new menu item links and integrate them into your site's configuration.
The submitForm()
method in a form controller is responsible for handling submitted data. This method can save data to the database (including updating configuration), trigger workflows based on user input, and redirect users after form processing. By the time data reaches submitForm()
, it has been validated and is ready for use.
In this tutorial, we'll:
- Add a
submitForm()
method to the form controller. - Save user-provided settings to the database.
- Confirm successful data submission to the user.
By the end of this tutorial, you'll understand how to implement custom submit handling logic in a form.
Hooks in Drupal enable modules to alter or extend the behavior of Drupal core or other modules. By implementing functions with specific names, modules can intervene at various points in Drupal's execution flow. This tutorial introduces hooks, their implementation, and their significance in module interaction.
In this tutorial, we'll:
- Define what hooks are.
- Explore how hooks are implemented in modules.
- Understand when modules should define and invoke new hooks.
By the end of this tutorial, you'll understand the concept of hooks as a means to alter Drupal's behavior.
Controllers are where you place the custom logic to dynamically generate the content of a page that a visitor sees when they visit a URL. When Drupal receives an incoming request, the HttpKernel identifies the appropriate route for the requested path, and the routing system matches this route with a controller. Controllers generate responses to these requests.
In this tutorial, we'll:
- Understand what a controller is in PHP and in the context of a Drupal module.
- Learn how to identify and interpret the role of a controller class.
By the end of this tutorial, you should be able to identify a controller class in a Drupal module and understand its role in generating responses.
Concept: Routes
FreeAs a module developer, you use routes defined in a module to add new URLs and tell Drupal which code to execute to build content for the page at those URLs. Central to this process is Drupal's routing system, built upon Symfony's Routing component.
In this tutorial, we'll:
- Introduce Drupal's routing system.
- Learn how modules can define new routes.
- Describe the roles that routes serve in a module.
By the end of this tutorial, you should understand each parameter of a route definition in a module's MODULE_NAME.routing.yml file.
As a development framework, Drupal core includes services for doing common things like accessing the database, sending email, or making HTTP requests. You can make use of these services to perform certain tasks, instead of recreating them in your own code. This means less custom code that you need to write and maintain. Generally speaking, almost everything that Drupal does is actually done by one of these objects. In Drupal, these objects are called services and in order to make working with them easier, they are primarily accessed through the service container.
In this tutorial, we'll:
- Explain the role of services in Drupal.
- Introduce the service container.
By the end of this tutorial, you'll understand the basics concepts of services and the service container in Drupal module development.