Often when building a site in Drupal you'll find yourself wanting to display a list of nodes, or find entities created by a particular author, or locate some content based on a particular set of criteria. Rather than querying the database directly, Drupal provides a helper class, EntityQuery
, to make things a bit easier. The EntityQuery
class will probably look very familiar to you if you're familiar with the Database API, or the EntityFieldQuery
class in Drupal 7.
In this tutorial we'll:
- Go through several examples of using
EntityQuery
to find subsets of content. - Demonstrate how to iterate over the results of an
EntityQuery
query.
By the end of this tutorial, you should understand how to use entity queries to create custom sets of data from entities.
Drupal's configuration system helps to solve the problem of moving changes in configuration from development to production. It does this in two ways: by providing a unified way to store configuration and by providing a process by which configuration changes can be imported and exported between instances of the same site. The configuration system is the result of work completed within the Configuration Management Initiative (CMI).
In this introduction, we'll provide:
- An overview of Drupal's configuration system
- Key concepts that you should know about
In the world of Drupal development, ensuring the security of custom code is paramount. Drupal's security standards and features offer a robust foundation, but developers must also adhere to security best practices to safeguard against vulnerabilities. From sanitizing output to prevent cross-site scripting (XSS) attacks to using Drupal's database abstraction layer to avert SQL injection, Drupal empowers developers to write secure code. But it's still up to you, the developer, to do so.
In this tutorial, we'll:
- Provide an overview of these practices.
- Introduces additional resources to increase your security expertise.
By the end of this tutorial, you should be able to articulate some of the common security risks and mitigation strategies for Drupal modules.
The Migrate Drupal UI module allows you to execute a migration from older versions of Drupal to the latest version of Drupal. In this tutorial we'll:
- Run a full Drupal 6 to latest-Drupal (Drupal 8 or 9) Migration from the UI
- Explore the user interface as it exists
- Understand how we can deal with the output from our migration
Source plugins extract data from a source and return it as a set of rows representing an individual item to import and some additional information about the properties that make up that row.
Anyone writing a custom migration, or module developers who want to provide a migration path from their Drupal 6 or 7 module, will need to work with source plugins.
In this tutorial we'll talk about the role that source plugins fulfill and how they work. By the end of this tutorial you should be able to determine whether or not you need to write a source plugin for your migration.
To follow along with the examples in this guide you'll need to have a copy of the Anytown Farmer's Market site that resembles what you would have if you went through all the chapters in the Drupal User Guide. If you did not follow along with the Drupal User Guide example, or if you need a fresh start, this tutorial will walk you through setting up a copy of the site based on a backup. This guide follows a project-based learning approach, and this setup is essential for ensuring that you can effectively follow along with the subsequent tutorials.
In this tutorial, we'll:
- Locate the codebase, backup database, and backup public files directory, required to restore a copy of the Anytown Farmer's Market site.
- Walk through setting up the site in DDEV using the provided backup.
By the end of this tutorial, you should have a working copy of the Anytown Farmer's Market site on your local development environment.
While Drush empowers all Drupal users with its commands, it's even more powerful when used in combination with scripting solutions such as Composer and Bash. Scripts can be used to power post-deployment tasks like importing new configuration or clearing the cache, as part of CI processes to sync a database from one environment to another, to run background processes on the server such as imports and migrations, search indexing, running cron, and much more. If you want to write Bash (or any other scripts) that interact with a Drupal site, then Drush is the tool for you.
In this tutorial we'll:
- Learn how to use Drush commands within Composer and Bash scripts
- Learn how to chain multiple Drush commands together in a script
By the end of this tutorial you'll know how to use Drush as part of a script that automates common or tedious tasks.
Views field handler plugins handle retrieving and displaying data within a view. The Drupal core Views module provides field plugins for all the core field types, and these work well for many situations where you need to describe custom data sets to Views. For situations where an existing plugin doesn't match your requirements, you can define a custom field handler plugin and alter both the query that gets executed and the rendered output of the data.
This is common for contributed modules that define new field types, or any module using hook_views_data()
to define a dataset to Views where the data contained in a database column may need special handling in order to be displayed as part of a view.
In this tutorial we'll:
- Implement a custom Views field handler plugin
- Extend the default date field plugin and modify the way that it displays a timestamp so that instead of a specific date we get a relative value
By the end of this tutorial you should know how to define a custom field handler plugin and use it in a view.
Views in Drupal
GuideAs 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.
The migration_lookup
process plugin allows you to populate entity reference fields when the entity that you want to reference is created by another migration, and you don't yet know what the unique ID will be in the Drupal database. Think of this as being able to answer the question: I have a migration that imports new users from a CSV file, and another that imports articles from a different CSV file. The articles' CSV file has a column that indicates which row from the users' CSV file is the author of this file. But in order to populate the author field for the Drupal node I need to know the ID of the imported user which is an auto-incremented ID that I'm not setting. So, what is the correct ID to use?
Another use case is circular dependencies, like hierarchical taxonomies with parent/child relationships. Or a content type with a field that references other nodes of the same type, like articles that reference other articles.
In this tutorial we'll:
- Learn about the
migration_lookup
process plugin and its configuration - Provide examples of using the plugin to populate entity reference fields during a migration
- Look at alternatives
By the end of this tutorial you should be able to use the migration_lookup
plugin to effectively manage entity relationships across multiple individual migrations.
In this tutorial we will run a site migration using Drush, and understand how to deal with any failures that occur.
Docker in Your Workflow
CourseIn the process of displaying the content of a view to an end user, every view goes through a common build cycle. As a developer it helps to understand the build and render cycle that a view goes through and how you can use it to alter the final result. It helps to know where things are in the cycle when your code is executed, and how that impacts what your code can and can't do. The Views module exposes hooks -- documented in views.api.php -- that allow developers to influence every step of the cycle. This includes altering the database query that gets executed, changing the configuration of filters, computing things based on raw results, and changing the rendered output of any field.
In this tutorial we'll:
- Learn the steps of the Views build and render cycle.
- Identify the hooks invoked during each step and provide examples of what types of things you might do with each hook.
By the end of this tutorial you should be able to list the hooks invoked by Views, when they get called during the build and render cycle, and explain the impact this has.
One method of creating a custom Drupal-to-Drupal migration involves using the Migrate Upgrade module to generate a set of migration configuration entities that you can use as a starting point. Even if you're not going to use the generated output in the end, this is still an informative exercise as it allows you to see examples of various migration paths.
In this tutorial we'll:
- Use the Migrate Upgrade module's Drush commands to import Drupal core's migration templates
- Examine the generated configuration entities
- Use the Migrate Tools module's Drush commands to view a list of the individual migrations that make up our Drupal-to-Drupal migration
By the end of this tutorial, you should be able to use the Migrate Upgrade module to generate the migrations that Drupal core would use to migrate content, list those migrations, and inspect them individually.
In this tutorial, you'll learn about the two types of configuration data: simple configuration and configuration entities. By the end of this tutorial, you should have a better understanding of which type of configuration to use in your module.
Developers can implement the Drush Command API to write their own custom Drush commands. This allows you to include Drush commands with your modules to allow the module's features to be used via the CLI. You can also create project-specific Drush commands that help with the development, deployment, and maintenance of your particular application.
We've written Drush commands to help generate reports, make it easier for new team members to get up and running, compile custom theme assets, and more. Any time we need to write PHP code that interacts with our Drupal site where we're worried the code might time out because it takes too long to execute we'll reach for Drush. Custom Drush commands are also useful to combine background processes that can be executed on cron, such as nightly imports, data synchronization, bulk database manipulation, custom queues processing, and so much more.
In this tutorial we'll:
- Learn about different types of custom Drush commands
- Review the anatomy of a Drush command
- See how the Drush bootstrap process relates to commands
By the end of this tutorial, you'll be able to identify the parts of a custom Drush command and start writing your own.
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.