PHP attributes are a native PHP language feature, introduced in PHP 8.0, that provide a way to add metadata to classes, methods, properties, and functions in PHP code.
In Drupal, this metadata is used by the plugin system to aid in the discovery and configuration of plugin instances. As a Drupal developer, it's important to understand how to recognize, read, and write PHP attributes, as you'll encounter them when working with plugins.
In this tutorial we'll look at:
- What PHP attributes are
- The use case for attributes in Drupal
- An overview of the attribute syntax
By the end of this tutorial, you should understand how attributes are used in Drupal and how to write them in your own code.
Prior to Drupal 10.2 most plugin implementations required the use of annotations alongside a PHP class. Now Drupal supports and recommends the use of PHP attributes instead. During the transition, most developers will still need to know how to recognize and implement annotation-based plugins.
In this tutorial we'll:
- Provide a recipe for implementing annotation-based plugins.
- Demonstrate how to figure out where the code and metadata should live for annotation-based plugins.
By the end of this tutorial you should have a recipe for getting started with implementing annotation-based plugins, and a better understanding of how to figure out the details required to implement a given plugin type.
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 learn how to add a property to a configuration entity in Drupal. Previously, we created a configuration entity called Transcode Profile and learned about the files and code that compose a configuration entity. Now, we'll add a new property called codec to this configuration entity and learn some new concepts in the process.
In order to add this new property to our custom configuration entity, we'll need to update our schema file, configuration entity forms, the entity list builder class, and add getter and setter methods to our main TranscodeProfile
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 in Drupal in a custom module. We'll be using Drupal Console's generate:entity:config
command to create and update the files in our Transcode Profile example module. After Drupal Console 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 Drupal Console to generate a configuration entity
- Identify files associated with a configuration entity and summarize the purpose and function of the code inside each file
- Find other examples of configuration entities in Drupal core
As a developer, within a module, you can define settings for the module and provide a configuration form for administrators to update the values of those settings. In this tutorial, we'll create a configuration settings form for a module and define default values for each setting. We'll use Drupal Console, a command-line utility for Drupal to do some code scaffolding and speed up the process.
By the end of this lesson, you should be able to get a basic settings form up and running inside a custom module complete with default settings and a menu link.
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
$config
array 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
Configuration entities are suitable for creating user-defined configuration, such as image styles, views, content types, etc. A configuration entity type is defined by a module, default configuration is provided by that module as well as any other module, and then users can create zero or more configuration entities through Drupal's administrative UI.
In this tutorial, you will learn about:
- What configuration entities are
- Configuration entity types versus configuration entities
- An example in core: image style
- Overview of the process of creating your own configuration entity types in a module
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.
In this tutorial, we'll cover how to load configuration entity data in a module. We'll change the AdminSettingsForm.php we created and replace the simple textfield we were using with a dropdown select list. Then we'll use data from our Transcode Profile module's configuration entity, loaded by the EntityTypeManager
via the services container, to choose our preferred Transcode Profile.
By the end of this tutorial, you should be able to:
- Know how to load configuration entities using
EntityTypeManager
via the services container - Update the AdminSettingsForm.php to use a dropdown select list
- Save your preferred transcode profile from a list of transcode profile entities
- Update the default configuration provided with the demo module to include transcode profiles
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.
Before we can actually get our field to store data for us we need to define what the data that we're going to store looks like. The Field API does this with hook_field_schema(), which uses a very similar syntax to what is used by the hook_schema() that modules can use to define database tables. In this particular case though we're only defining what the column, or columns, that store our specific data will be and allowing the Field Storage API to decide what the structure of the created table, or tables, should be. This allows our field to remain mostly storage system agnostic and frees us from having to worry about things like how the stored field data is connected back to the entity that it belongs to, or how to format our table for proper handling of revision data or translations.
- Documentation for hook_field_schema - https://api.drupal.org/api/drupal/modules%21field%21field.api.php/funct…
- Schema API docs - https://drupal.org/developing/api/schema
Example hook_field_schema()
implemenatation.
/**
* Implements hook_field_schema().
*/
function rgb_field_schema($field) {
$columns = array(
'rgb' => array(
'type' => 'varchar',
'length' => 6,
'not null' => FALSE,
),
'label' => array(
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
);
$indexes = array(
'rgb' => array('rgb'),
);
return array(
'columns' => $columns,
'indexes' => $indexes,
);
}