Modules in Drupal often rely on the Configuration API to adapt their behavior based on administrator-defined settings. This involves both reading values from configuration objects in custom code and enabling administrators to modify these values with a settings form.
In this tutorial, we'll:
- Demonstrate accessing configuration data with the
config.factory
service. - Examine the module's settings form's interaction with the Configuration API.
- Adjust the
WeatherPage
controller's behavior based on administrator-defined configuration.
By the end of this tutorial, you should be able to read and output simple configuration data within a module.
Modules must provide metadata about their configuration data via a schema definition, which serves localization and validation purposes. Modules can optionally specify default configuration values to ensure that the module functions when installed.
In this tutorial, we'll:
- Define schema for the Anytown module's configuration.
- Set default module settings.
By the end of this tutorial you should be able to define a configuration object's schema and default values.
Dependency injection is an object-oriented programming design pattern widely used in Drupal. Instead of a class creating an object directly, dependency injection provides services or objects to a class externally, and is an example of the Inversion of Control principle.
In this tutorial, we'll:
- Explain dependency injection in the context of Drupal.
- Take a look at examples of constructor and setter injection in Drupal code.
By the end of this tutorial, you'll recognize dependency injection patterns and understand how it's used in Drupal module development.
Entity queries are the standard method for retrieving, filtering, and sorting lists of entities programmatically in Drupal. Unlike direct database queries, entity queries work seamlessly with Drupal's entity system, including support for access control and abstraction from storage details.
In this tutorial, we'll:
- Introduce entity queries and their operation within Drupal.
- Explain the advantages of using entity queries over direct database queries.
- Provide examples of entity query usage.
By the end of this tutorial, you'll understand how to efficiently and securely fetch lists of entities using entity queries.
Updating entity field values involves loading the entity object, modifying field values, and saving the entity to the database. We'll add a submit handler in our form that uses Entity API methods to update the vendor entity with new attendance data from the form.
In this tutorial, we'll:
- Update and save an entity's field values.
- Implement a submit handler in the attendance form to update the vendor entity with new data.
By the end of this tutorial, you should be able to modify an entity's field values and save the updated entity.
Learn how to use a cron job combined with an entity query to reset the attending status of vendor nodes every week. This will ensure that the vendor entity data only contains current check-ins.
In this tutorial, we'll:
- Implement
hook_cron()
within the Anytown module. - Use an entity query to identify all vendor nodes requiring updates.
- Apply Entity API methods to reset each vendor's attending status.
By the end, you'll know how to execute an entity query, retrieve nodes, and update their status with cron.
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
andlogger.factory
services. - Update the
build()
method of our controller to use the provided services 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 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.