Every module must have an info file that provides Drupal with metadata about the module. Drupal uses this file to recognize that the directory the info file is contained within, along with the files inside it, are part of a module. Without an info file, Drupal will not recognize your code as a module, and the code will be ignored. Info files are written in YAML and contain information like the module's name, versions of Drupal it's compatible with, and a description.
In this tutorial, we'll:
- Pick a name for our custom module and create a directory for it.
- Create an .info.yml file with metadata about our module.
- Install our new custom module to verify Drupal can locate it.
By the end of this tutorial, you should have a directory for your custom module's code and an info file that tells Drupal this directory contains a module.
Routes map URLs to the code that generates the content for display. As module developers, we create routes whenever we want to add a new URL with code. Our task is to create a route for a page displaying the weekend weather forecast. We start by defining the route, then add the corresponding controller.
In this tutorial, we'll:
- Create a routing YAML file for a custom weather page.
- Define a route instructing Drupal to point the path /weather to our custom code.
By the end of this tutorial, you will have defined a route for your weather page, including the path and a reference to the controller managing the content.
Route parameters enable a single route and controller to handle multiple URLs by passing dynamic values from the URL to the controller. This allows for more versatile and responsive page content generation.
In this tutorial, we'll:
- Understand the function of route parameters.
- Update the
anytown.weather_page
route to include parameters. - Modify the
WeatherPage
controller to use these parameters.
By the end of this tutorial, you'll know how to use route parameters to pass dynamic values to controllers.
The life cycle of a Drupal form, from initial request to final processing, involves multiple stages. This tutorial outlines these stages and the role of form controllers, which contain custom form handling logic.
In this tutorial, we'll:
- Define the role of a form controller.
- List the phases of form processing in Drupal and how to add custom logic to each.
- See how form controllers relate to routes for displaying full-page forms.
By the end of this tutorial, you should be able to explain the role of a form controller and how to get started creating a new one.
Controllers in Drupal frequently need to use services to figure out what information to display on the page. This might include querying for a list of entities, getting information about the current user, or accessing saved configuration. It's a best practice to always use dependency injection to supply services to a controller. In the anytown module we can improve the WeatherPage
controller by making it access a weather forecast API to get up-to-date data.
In this tutorial, we'll:
- Set up a mock weather forecast API.
- Refactor our
WeatherPage
controller to inject thehttp_client
service. - Update the logic in the
build()
method of our controller to use the provided service to get and display a weather forecast.
By the end of this tutorial, you should be able to use dependency injection to give a controller in a Drupal module the services it requires, and then make use of those services in building the page content.
If we use parameter upcasting in our entity route definition, we can simplify code in the StatusUpdateForm
controller. Parameter upcasting works by instructing Drupal to load entity objects referenced in a route's path automatically. This approach reduces boilerplate code related to the entity type manager service and entity object loading.
In this tutorial, we'll:
- Define parameter upcasting and its advantages.
- Update the
StatusUpdateForm
controller with type hinting to use parameter conversion services. - Refine our route definition's access checking for entity-specific verification.
By the end of this tutorial you should be able to use parameter upcasting to load full entity objects through an updated route definition.
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 PHP attribute 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.