Many of Drupal's APIs that look like a bunch of configuration in a YAML file (migrations, menu links, etc.) are actually plugins in disguise. The YAML from these files is used as arguments to a generic PHP plugin class which then behaves differently depending on the provided values. As a developer, you probably don't need to know that menu links are plugins, but it can be helpful when debugging or just trying to get a better understanding of the big picture.
In this tutorial, we'll:
- Learn about how YAML-based plugins work
- Discuss how to find the implementation details for YAML-based plugins
- Walk through an example of implementing a YAML-based plugin
By the end of this tutorial, you should be able to recognize a YAML-based plugin definition, and author your own.
In this tutorial, you’ll create and render a simple single directory component (SDC) in Drupal. You’ll set up the required files, call the component from a template, and confirm that Drupal renders it with its styles automatically attached.
By following along, you will:
- Scaffold the files for a basic card component.
- Reference the component in a node template.
- See how Drupal renders the component’s HTML and CSS together.
When you’re done, you’ll have a complete working example of a Drupal single directory component.
As a module developer, you output themed content from your module in the form of renderable arrays. When doing so, you can make use of single directory components (SDCs) by using the #type => 'component' render element type. This allows modules to dynamically select and configure a component based on configuration or specific PHP logic. You'll use this as the return value of a controller, or a configurable plugin related to display building, like custom blocks or field formatters. As an example, we'll author a custom block plugin that loads a specific node and outputs it using the card SDC we defined in a previous tutorial. We'll build a render array that supplies the values for the component's props and slots, and add some caching logic to the output.
In this tutorial, we will:
- Build a render array that targets an SDC via the
#componentproperty. - Pass data into the component's props and slots, and demonstrate optional
#propsAlterand#slotsAltercallbacks. - Validate the output and cache it properly.
By the end of this tutorial, you'll be able to render any SDC via a module's PHP code using a well-structured and cache-friendly render array.
A Drupal single directory component (SDC) is Drupal's way of packaging the markup, metadata, styles, and behavior for a UI element in one self-contained folder inside a theme or module. This structure helps front-end developers and site builders keep all related files together for easier theming and reuse. A Drupal single directory component directory must be located in a specific place and its files named with a particular convention so that the system can discover it and use its assets.
In this tutorial, we'll:
- Show where Drupal discovers single directory components in your codebase.
- Explain the naming and organization conventions for Drupal single directory component directories and files.
- Outline key files for a component—both required and optional.
By the end of this tutorial, you'll be able to identify an SDC directory in a Drupal module or theme and know exactly what you're looking at.
Props and slots are the two ways that data can be provided to a single directory component (SDC). They are part of a component's schema definition, and are used to determine the names of variables passed to a component's template file. Props pass structured, validated data into a component, while slots allow us to inject flexible content such as HTML or nested components. Understanding when and how to use each ensures you can build reusable and adaptable components.
In this tutorial, we'll:
- Learn what props and slots are, and how they differ.
- Discuss how using one or the other impacts the developer experience and use of your components in a UI.
- Practice deciding when to use each for component design.
By the end of this tutorial, you'll know how to choose between props and slots when building components.
Learn how to generate menu links dynamically with plugin derivatives in a custom module. This tutorial walks through creating a single base menu link plugin definition and a deriver class that expands that definition into one menu link per content entity. The code will automatically generate links for all published basic pages, placing dynamic menu links in the main menu.
By the end of this tutorial, you should be able to:
- Understand which files you need in order to define menu link plugin derivatives, also known as dynamic menu links
- Create the necessary code to define menu link plugin derivatives for an example use case
This reference document contains a detailed list of available properties for the #[ContentEntityType] attribute in Drupal 11. The current documentation in the Drupal 11 code base lists, but doesn't always describe, each of these properties. Or, in many cases, the property is an associative array where the nested key/value pairs are important, but what they should be isn't well documented. So we've created this helpful reference. Most of the properties listed here will also apply to #[ConfigEntityType] attributes. These properties define the metadata and behavior of custom entity types.
In this tutorial, we'll:
- Look at an example of how to use
#[ContentEntityType]attributes. - Provide a comprehensive list of available properties and a description of each.
- Show detailed examples of using nested array properties like
handlers[].
By the end of this tutorial, you should be able to understand how and when to use any of the properties of a #[ContentEntityType] attribute in order to modify the behavior of a custom entity type.
Drupal stores the settings that define how a site behaves as configuration data. Everything from the site name to image styles, roles, and view definitions are stored as configuration. The Configuration API gives modules, themes, and installation profiles a consistent way to store, retrieve, update, and provide this configuration in a structured and portable way.
In this tutorial, we'll:
- Provide a high-level overview of the features of Drupal's Configuration API
- Link to related tutorials where you can learn more and get hands-on practice working with configuration data in code.
Bundle classes are a feature of the Drupal Entity API that let you attach PHP classes to individual bundles (for example, content types) so you can keep site-specific business logic close to the data it acts on. Bundle classes are a powerful way to encapsulate site-specific business logic and bridge user-configured fields and PHP logic based on those fields. In this tutorial, you will build a reusable bundle base class that adds a generic share behavior for all node types on a site and then extend it for a specific node type.
In this tutorial, we will:
- Explore a real-world problem that bundle classes can help you solve.
- Create a bundle base class for common share features shared across multiple node types.
- Implement a node-type-specific class that extends the base class with behavior tailored to the underlying content type.
By the end of this tutorial, you'll be able to use bundle classes to encapsulate per-bundle logic, assume the presence of UI-configured fields when appropriate, and register those classes so Drupal uses them at runtime.
Drupal recipes provide a new way to package and share reusable features across Drupal sites. Unlike traditional install profiles or distributions, recipes are applied once to add functionality and then step out of the way, leaving you with a standard Drupal site that you can customize freely.
In this tutorial, we will:
- Understand what Drupal recipes are and how they differ from install profiles and distributions
- Learn the four core properties that make recipes powerful: applied (not installed), shareable, non-locking, and composable
- Explore real-world scenarios where recipes solve common platform and agency challenges
By the end of this tutorial you'll be able to explain what Drupal recipes are, identify features in your projects that are good candidates for recipes, and articulate the value of recipes to stakeholders.
Recipes transform your Drupal site by adding features and configuration. After downloading (or authoring) a recipe it needs to be applied to your Drupal project. This is analogous to following the step-by-step instructions in a recipe to make a dish. Only, we're not performing the steps on our own, but instead we're using Drupal's tools to apply the recipe. Applying the recipe adds its features to your Drupal project. This requires establishing safe workflows to apply recipes, verify their effects, and roll back changes if needed.
In this tutorial, we will:
- Apply a recipe in a non-production environment using a feature branch workflow.
- Review configuration changes using Git and verify functionality in the UI.
- Understand how to roll back recipe changes if needed.
- Learn safe workflows for both developers and non-developers.
By the end of this tutorial, you'll be able to safely apply recipes to your projects, review their impact, and decide whether to keep or roll back the changes.
The built-in config actions in Drupal core cover most common scenarios. But sometimes you need custom operations specific to your feature or the configuration your module relies on. You can create custom config actions by defining them as plugins or by adding PHP attributes to a configuration entity class's methods. Let's implement a custom config action to toggle an SEO strict mode setting to learn how to extend recipes with domain-specific configuration operations and make them reusable across your projects.
In this tutorial, we will:
- Identify scenarios where custom config actions are warranted.
- Understand the two implementation patterns: plugins and attributed methods.
- Implement a custom config action in a module.
By the end of this tutorial, you'll be able to implement custom config actions that extend the configuration API provided to your recipes, making platform-specific operations reusable and declarative.
The Configuration Actions API lets recipes modify existing configuration rather than just adding new configuration. By extending the SEO Article recipe created in a previous tutorial with config actions, you'll learn how to manipulate existing configuration objects in order to do things like grant permissions and modify entity display modes. This is necessary because sometimes a recipe needs to modify configuration that already exists on the site, not just add new configuration.
In this tutorial, we will:
- Add config actions to grant permissions to existing roles
- Modify entity displays using config actions
- Reapply recipes and observe idempotent behavior
- Experiment with new content types to understand recipe limitations
By the end of this tutorial, you'll be able to use common config actions in your recipes and understand how recipes behave when reapplied.
The Configuration Actions API is a powerful feature of Drupal recipes that allows you to modify existing configuration without replacing it entirely. While configuration exports let you add new configuration, config actions let you update what's already there—like granting permissions to an existing role or adjusting display settings. Effectively, config actions are a way for a recipe to declare a PHP method to run on a configuration object during recipe application and any arguments that method needs to run.
In this tutorial, we will:
- Understand what config actions are
- Learn how to read and write config actions in a recipe's YAML file
- Explore common patterns like granting permissions and modifying displays
- Understand the difference between generic and type-specific actions
By the end of this tutorial, you'll be able to read config actions in recipes, understand when to use them versus configuration exports, and recognize common config action patterns.
Creating your own recipes lets you package and reuse features across your projects. By building a simple SEO-focused recipe from scratch, you'll learn what goes into a recipe, how to declare dependencies, and how to test your work.
In this tutorial, we will:
- Understand what belongs in a recipe versus what belongs in modules
- Create a recipe structure with proper metadata and dependencies
- Export and package configuration into a recipe
- Test the recipe by applying it to a second site
By the end of this tutorial, you'll be able to create your own recipes, package them properly with dependencies, and apply them to other Drupal sites.
Fields are the building blocks of Drupal's powerful content modeling system. The field API allows for the development of custom field types to suit almost any data display and collection needs. Developers can create custom field types that can be bundled together and attached to various pieces of content. Fields allow a Drupal Site Administrator to create an information architecture that matches the needs of each individual site.
This series will provide you with all the information you need to be able to define a custom field in your own module. After completing all the lessons in this series, you should have a firm grasp of the Drupal 7 field API and the tools and knowledge you need in order to define your own custom field types.
Prerequisites
This series requires an understanding of PHP and basic Drupal 7 module development. For a refresher, or if you get stuck, check out our Drupal 7 Module Development series.
Additional resources
Drupal 7 Module Development series (Drupalize.Me).
Before diving into the code it's important to understand some of the building blocks that make up the Field API. There's a lot of different terminology in the Field API and it helps to understand what each of the terms mean. As well as understanding the relationship between the Fields and Entities in Drupal 7. Knowing these things will give you a strong foundation on which to start exploring the Drupal 7 Field API.
Terms & concepts covered in this video:
- What is a field? what is an instance?
- How do fields relate to entities?
- Field types
- Field storage
- Field widgets
- Field formatters
For more information about these terms see the Drupal.org handbook page: https://drupal.org/node/443540
- Field CRUD API - creates field instances and bundles, e.g.) what you see on the manage fields page.
- Field attach API - connects entities and fields, uses info from Field Info API to retrieve defined fields and do things like display their widget on the appropriate entity form when someone tries to edit an entity.
- Field info API - retrieve information about defined fields and instances.
- Field storage API - pluggable back-end storage for fields. Defaults to SQL backend provided by core.
- Field language API - provides native multilingual support for fields.
There's quite a bit of documentation and other resources already available to help you better understand the Drupal 7 Field API. Lets take a look at what's already available on Drupal.org, in the Examples project, and in the Drupal 7 core code that will serve as good reference material. We'll be referring back to these resources in later lessons, and they'll serve as a great place to look up additional information or to continue your learning via other examples.
Resources covered in this video:
- The Drupal.org Handbook for Field API
- API documentation in field.api.php, which gives an overview of all the Field API hooks.
- Field API documentation available on api.drupal.org - https://api.drupal.org/api/drupal/modules%21field%21field.module/group/…
- Examples for Developers project
We've also got some additional resources here on Drupalize.Me that will serve as a good refresher for how/where fields are used in Drupal:
- For learning more about how to use fields in the UI and how the UI works - http://drupalize.me/series/intro-fields-site-builders-series
- Attaching fields to custom entities - http://drupalize.me/videos/make-your-entity-fieldable-bundles
Additional resources
Before we can start building our custom field we need a vanilla Drupal site to work with and a skeleton module. This lesson will ensure you've got Drupal 7 up and running and walk through creation of a basic .info file and .module file for the module we'll be building. If you're already familiar with Drupal module development this lesson can likely be skipped and you can simply download the attached starter files, add them to an existing Drupal site, and continue on with the next lesson.
Grab a fresh copy of Drupal 7, and install it. If you need a refresher on installing Drupal checkout this series.
You'll also want to download and install the devel module as we'll make use of some of the debugging functions in provides (namely dsm()) in later lessons in this series.
Alternatly, you can grab the .zip file under the companion files listed on this page which contains Drupal 7, and a database dump you can import to get started.
The first step to defining a custom field is telling Drupal that our module provides a field. This is done by implementing hook_field_info(), hook_field_formatter_info(), and hook_field_widget_info(). The combination of which provides some basic information about our field including a label, description, default settings, and basic information about how the field will be formatted and what widgets can be used for data collection.
In this lesson we'll implement the basics for the following hooks:
Doing so will allow us to enable our module and see our new field type appear in the list of available fields to add to a content type. The field won't do much beyond that yet, but it's a good start towards telling Drupal about our custom RGB field type.
If you want to just follow along and look at the already written code you can grab a copy in the companion files section of this page and use that to follow along.