Drupal site administrators can create new media entity types, with their own unique configurations and sets of associated fields. Different media types can be configured with different field names, permissions, moderation workflows, and display settings, making it possible to create truly custom content administration experiences. The process is similar to creating a node content type like articles or events with one major distinction: every media type inherits from a specific media source plugin. The source plugin provides domain-specific knowledge about the kind of resource being represented. For example, the Remote video source plugin used with the default Remote video media type knows how to consume and display videos from YouTube and Vimeo given only their URL.
Drupal core comes with a couple of common media source plugins, and contributed modules and custom code can add to this list, increasing the different media providers with which Drupal can integrate.
In this tutorial we'll learn how to:
- Install a contributed module that provides a new media source plugin.
- Create a new media type.
By the end of this tutorial you should be able to explain how source plugins relate to media types, and create a new media type.
The Drupal Media Library and Media ecosystem can be integrated with any third-party media provider by defining new media source plugins. Media types (Media entity bundles) have an important distinction compared to other content entity types like nodes. Every media type inherits from a specific media source plugin. The source plugin provides domain-specific knowledge about the kind of resource being represented. For example, media types dealing with images know how to validate file extensions and render <img> tags. Media types dealing with remotely hosted videos might know how to retrieve thumbnails from a remote API, and display an HTML video player and transcript.
In this tutorial we'll learn how to:
- Define a new source plugin
- Integrate a third-party API via its existing PHP library
By the end of this tutorial you should be able to create a new source plugin that exposes any third-party media resources you want to integrate with Drupal.
If the Media assets you want to use in your library support oEmbed, then you might be able to use them with a minimal custom code. Before you go down the path of creating a custom media source plugin try this approach first.
oEmbed is a standard way of allowing third party sites to embed an asset represented by a URL. The Remote Video source in core uses the oEmbed features of YouTube and Vimeo. When you paste a link into a Slack channel, and it displays a pretty card preview, or an embedded video or Spotify playlist, that's oEmbed in action. Does the Media you want to embed have a canonical URL? If so, paste it into the tool here and see if it displays oEmbed info in the results.
In this tutorial we'll:
- Learn how to enable additional oEmbed providers as Media sources
- Use the contributed oEmbed Providers module for compatible providers
- Demonstrate how to create a custom oEmbed media source plugin to further customize the results
By the end of this tutorial you should be able to embed any oEmbed-compatible content as Media assets in Drupal.
Media source plugins provide the link between media entities in Drupal and the actual media asset itself. They are the code that understand the difference between an image, a video, and a Tweet, and perform the translation that allows the media ecosystem to treat all media entities equally. For example, local image files, and remote YouTube videos, can both be catalogued in a similar way as media entities, but they need very different handling when it comes to displaying them.
Media sources are represented as plugins, there are a handful in Drupal core, and a developer can add new plugins to represent any type of media your application needs to catalogue.
In this tutorial we'll learn:
- How media source plugins relate to Media Types
- The responsibilities of a media source plugin
By the end of this tutorial you should be able to define the role of a media source plugin and understand what's required to define your own.
In this tutorial, you'll learn how to add a property to a configuration entity type in Drupal. Previously, we created a configuration entity type called video_preset and, using Drush, scaffolded the files and code to define a custom configuration entity type. Now, we'll add a new property called codec to this configuration entity type and update the code we created in the previous tutorial.
To add this new property to our custom configuration entity type, we need to update our schema file, configuration entity forms, the entity list builder class, and add getter and setter methods to our ConfigEntityType class.
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.
In this tutorial, we’re going to walk through the process of creating a custom configuration entity type in Drupal in a custom module. We'll be using Drush's generate entity:configuration command to create and update the files in our example module. After Drush has generated and updated the files for our configuration entity, we'll walk through each file and see how they define data structure, metadata, an administrative interface, and menu links for a configuration entity in Drupal.
By the end of this tutorial, you should be able to:
- Use Drush to generate a configuration entity type
- Identify files associated with a configuration entity and summarize the purpose and function of the code inside each file
When you are developing a module in Drupal, you can make certain functionality user-configurable. You can see this on Extend (admin/modules) in Drupal's administrative UI by looking for the Configure link near the module's description. To accomplish this, your module needs to define default settings in config/install/transcode_profile.settings.yml, create a settings form that will read those settings as the values for corresponding form fields, and update the settings when the form is submitted with updated values.
In this tutorial, we'll create a settings form that will be used as the module's Configure link in the Extend UI, as well as a menu link in an appropriate place in the administrative area. We'll use Drush, a command-line utility for Drupal, to speed up the process. We'll also create a default settings YAML file so that the settings form has something to read and update.
By the end of this tutorial, you should be able to get a configuration form up and running inside a custom module that will read and update a configuration object's values.
As we learned in Configuration Data Types, simple configuration is suitable for storing module settings as boolean values, integers, or text strings in one or more key/value pairs. In this tutorial, we'll walk through creating a schema and providing default configuration to store initial settings that a module needs to function.
Not every environment or copy of a site you may be working on will be created equally. You may want to enable logging on a development site or need to use different API keys depending on the environment. But you also need to make sure that your instance-specific configuration overrides don't make it into the database, mistakenly get exported, or compromise security.
In this tutorial, you will learn how to:
- Override the global
$configarray in settings.php (or settings.local.php) - Retrieve overridden (immutable) configuration (read-only mode)
- Retrieve original (mutable) configuration for updating (read/write mode)
- Set dynamic values for configuration instead of overriding values
When you create a module for Drupal, it can be useful to provide default configuration. This can be settings for a form, the placement of a block, or something more complex like the default image styles provided by the Image module in core. A module can provide default configuration for simple configuration or configuration entities.
In this tutorial, we will cover:
- Possible locations for default configuration
- What happens with configuration when a module is installed or uninstalled
- Managing dependencies in configuration
- Where to find examples of default configuration
When working on configuration in a module, whether as part of a migration that uses Migrate Plus configuration entities, or while developing custom configuration entities, you'll often need to re-import the configuration stored in the .yml files of the modules config/install/ or config/optional/ directories. This is tricky though, because Drupal only reads in those default configuration settings when the module is first enabled. So any changes you make to those files after the module has been installed will not be reflected without these workarounds.
Knowing how to do this can improve the developer experience of adding (or debugging) the default configuration that's provided with a module. Or for anyone using Migrate Plus configuration entities as part of a migration.
In this tutorial we'll:
- Learn about the Configuration Development module
- Look at how you can use Drush to perform a partial configuration import
- Write an implementation of
hook_uninstall()to remove a module's configuration when it's uninstalled
By the end of this tutorial you should be able to re-import the configuration provided by a module without having to uninstall and then reinstall the module.
Now that we have some default simple configuration stored in a settings YAML file, let's utilize it in a form that our site administrators can use to update those values. We'll make use of some services and methods in Drupal's Configuration API in order to retrieve, update, and save simple configuration values with a form.
While we've already created configuration entity forms for creating, editing, and deleting configuration entities, in this tutorial, you'll learn how to use configuration entity data in the context of a module's settings (configuration) form. We'll refactor the module settings form we created previously and replace the textfield form element with a dropdown select list of our custom video preset configuration entities we created in another tutorial.
By the end of this tutorial, you should be able to:
- Load configuration entities using an injected
entity_type.managerservice - Update the module settings form to use a select list of configuration entities
- Save the settings form with the refactored field
In addition to using one of the existing generators, developers can write their own Drush generator commands. This can help speed up repetitive tasks and reduce the use of boilerplate code that is prone to human error.
Generators are provided through Drush's integration with the Drupal Code Generator project. Writing new generators isn't specific to Drush, though if you're creating generators for Drupal it is definitely easiest with Drush as a wrapper.
Similar to Drush commands, generators can be supplied by a Drupal module or declared globally. If you have a feature-specific functionality, it's best to ship your custom generator within the custom module. Otherwise, a global generator can be declared and used.
In this tutorial we'll:
- Explain the anatomy of a Drush generator
- Write a custom Drush generator for handling a site's development.services.yml file, and use it in a project
By the end of this tutorial you should understand how to create, or customize, a Drush code generator and use it in your project.
Code generators are great productivity boosters that allow generating scaffolds for common development tasks in Drupal. One of the most common use cases for generators is scaffolding the code required for a custom entity type. Custom entities require many files and complicated annotations in order to function properly. There is a lot of boilerplate code that is more-or-less the same for every entity type. Creating all the files is repetitive, time-consuming, and prone to human error. Generators can help automate this task and make creating your own custom entity types quicker.
In this tutorial we'll:
- Learn how to generate the code for a custom entity with Drush
- Learn about the options that generators provide for custom entities
By the end of this tutorial you should know how to generate custom entities with Drush.
The Drupal Entity API makes it easy to define new custom content entity types. And in most cases, whenever you want to store custom content in Drupal, you should use the Entity API instead of making CRUD queries directly to the database. This ensures your code is more consistent and allows you to take advantage of all the features of the Entity API, like access control, Views module integration, and automatic JSON:API support. As well as making it easier for others to extend your custom content by ensuring all the proper hooks and lifecycle events get invoked when new content items get created, updated, and deleted.
In this tutorial, we'll:
- Walk through the process of creating a custom content entity
By the end of this tutorial, you'll be able to create your own custom content entity contained in a module.
One of Drupal's strengths is its fine-grained permission and access system. The Entity API enables this by providing interfaces that let us define access control rules.
In this tutorial we'll:
- Look at how access control is handled, using Drupal core as an example.
- Demonstrate how to implement access control in a custom module.
- Learn about the hooks that allow developers to modify access control for entities provided by another module.
By the end of this tutorial you should have a better understanding of the entity access control system and how to work with it.
Entities are the core data structures that provide the building blocks for nearly everything on a Drupal site. Whether an entity provides configuration or content, it plays a key role in how Drupal stores and manages data. Entities provide a consistent, developer-friendly, and Drupal-aware abstraction to data stored in the database.
In this tutorial, we will:
- Explore how different entity types relate.
- Compare configuration and content entities to understand the purpose and implementation of both.
- Review how (at a high level) an entity type is defined.
By the end of this tutorial, you'll understand the relationship between configuration and content entities and be able to identify the parts of code that define a custom entity type.
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
EntityQueryto find subsets of content. - Demonstrate how to iterate over the results of an
EntityQueryquery.
By the end of this tutorial, you should understand how to use entity queries to create custom sets of data from entities.