Concept: Render API
FreeDrupal's Render API plays a crucial role in how content is presented on a site. The Render API manages how content is rendered through render arrays and render elements.
In this tutorial, we'll:
- Define render arrays, highlighting properties and elements.
- Explain how render elements are used as shorthand for complex structures.
- Describe the primary types of data we can use in a render array.
- Touch on the role of renderers and special methods for rendering entities.
By the end of this tutorial, you'll better understand how Drupal constructs a page's output through render arrays and streamlines rendering with render elements.
Every introduction to coding starts with a "Hello, World!" example, right? With Drupal, it's a bit more complex than just echo "Hello, World!"
. To follow Drupal best practices, we should provide content from our custom code in a way that allows a site administrator to choose where and when it's shown, instead of hard-coding those decisions. This keeps our Drupal application flexible and customizable.
In this tutorial, we'll:
- Author a custom block plugin that outputs the string "Hello, World!".
- Place the block on the home page of our site.
By the end of this tutorial, you should have written the code for a custom block that can display the string "Hello, World!".
Whenever your custom code outputs a render array, you need to use the #cache
property to define the cacheability of the content. This includes providing information about any related context that informs Drupal about how the content varies, and tags that help Drupal know what circumstances might require the cached data to be invalidated. We can add #cache
properties to the render arrays output by both the custom block, and the weather page controller, to ensure they are properly cached.
In this tutorial, we'll:
- Learn how to use the
#cache
property of a render array to provide cacheability data to Drupal. - Provide context about the data that's being displayed.
- Tell Drupal about any dependencies of the content.
By the end of this tutorial you should be able to use the #cache
property to define the cacheability of the content contained in a render array.
Implementing plugins often involves accessing Drupal services to use their functions. Since plugins are PHP classes, we can use dependency injection to access services in our class. This tutorial demonstrates injecting dependencies into plugin classes. We'll update the HelloWorldBlock
class to use the current_user
service through dependency injection.
In this tutorial, we'll:
- Learn how to inject dependencies into plugin classes.
- Update the
HelloWorldBlock
class to use dependency injection for accessing thecurrent_user
service.
By the end of this tutorial, you should understand how to use dependency injection within plugin classes.
Settings forms are commonly used in Drupal modules to allow administrators to manage a module's configuration. This tutorial will guide you through creating a settings form for the Anytown weather forecast module, enabling site administrators to customize the location for weather forecasts.
In this tutorial, we'll:
- Define a new form controller for a settings form.
- Build a
$form
array with options for the settings form. - Associate the form with a route and menu item.
By the end of this tutorial, you'll have a custom settings form that administrators can access.
Installing community-contributed Drupal modules can enhance your project's functionality without the need to develop custom code. It's common to find a module that almost meets your needs but requires updates or additional features. Engaging with the module maintainer and other community members to improve these modules enriches the Drupal ecosystem and aligns with the open source values of collaboration and shared progress. This tutorial outlines how to actively participate in the development of contributed modules by filing issues, submitting patches (through merge requests), and collaborating in issue queues.
In this tutorial, we'll learn:
- The benefits of using contributed modules over custom code.
- The importance of collaboration in the Drupal community.
- Where to learn more about participating in the development of contributed modules.
By the end of this tutorial, you should understand how to enhance and contribute to Drupal's contributed modules ecosystem.
Deciding to share your custom module with the Drupal community can significantly impact both your project and the wider Drupal ecosystem. Contributing modules not only helps enrich the community but also provides a platform for feedback, improvement, and collaboration.
In this tutorial, we'll:
- Explore the benefits of contributing modules to the Drupal community.
- Discuss the key considerations for preparing your module for contribution.
- Highlight the trade-offs between contributing a module and maintaining custom code.
By the end of this tutorial, you should understand the value of contributing to the Drupal project and know what steps to take to prepare your module for contribution.
The Configuration API provides a standardized method for storing and managing a module's settings in Drupal. This tutorial covers the concepts of active configuration, simple configuration, configuration entities, and configuration schemas, and how to interact with, create, and retrieve configuration data.
By the end of this tutorial, you'll have a better understanding of how to work with configuration data in Drupal, focusing on simple configuration for module settings.
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.