Plugin Definitions
Plugins play an integral role in facilitating user interface components. While the plugin system can be used for more situations than this one, all of its components conspire together to make this use case really shine. In order to help facilitate this a set of metadata or "definitions" are associated with every single plugin. This data can vary from one plugin type to the next with only a handful of required keys. Plugin definitions have an analog within the more traditional Drupal approach as info hooks. The plugin system has however built an abstraction layer around what we call Discovery. This is a separate topic, but plugin definitions play a vital role in how discovery works.
The most basic approach a plugin definition can take is simply defining the class the plugin utilizes, and the plugin id as a key to this array. If we were to define a block plugin for menus (i.e. MenuBlock) at bare minimum it would have to look like this:
<?php
array(
'menu_block' => array(
'class' => 'Drupal\system\Plugin\block\block\MenuBlock',
),
);
?>Plugin Derivatives
One of the most powerful portions of the plugin system is its ability to help inform the user interface components of a system and allow your end users to choose which plugin option(s) they want to use. Typically options presented in this manner have a one to one relationship of options to plugins, however this is not strictly a requirement, and when looking at things that are expanded via user input, this is actually undesirable. For this example we will discuss blocks.
All blocks are available to the user through the user interface, for most blocks this is fine, the "Powered by Drupal" block can be a single plugin and it will never matter, however the menu block(s) all require the same logic but need different options within the user interface. Furthermore, when a site builder creates a new block, that block should be available in the UI for placement. DERIVATIVES TO THE RESCUE!!!
Derivatives provide a simple way to expand a single plugin so that it can represent itself as multiple plugins in the user interface. This is done by creating a separate class for this purpose and referencing it appropriately in your plugin definition. For this example we will assume a plugin definition being returned from a hook discovery method for the hook hook_block_info that looks like this:
<?php
function system_block_info() {
return array(
'menu' => array(
Discovery Decorators
A discovery decorator is a class which wraps another discovery mechanism in order to provide additional functionality. Discovery decorators conform to the same interfaces as regular discovery classes, but they are intended to be used in tandem with another discovery class. Discovery decorators should take a DiscoveryInterface typed variable in their __construct method and any other parameters that are necessary to make them work. There are two included discovery decorators in core, we'll look at the CacheDecorator first.
Drupal\Core\Plugin\Discovery\CacheDecorator
We'll discuss the various methods that exist here and what they do.
public function __construct(DiscoveryInterface $decorated, $cache_key = NULL);
As mentioned above, this function takes a DiscoveryInterface compatible variable called $decorated. This could be any of the previously discussed discovery classes. In addition to this it takes a $cache_key which will be used when making cache()->get() calls.
public function getPluginDefinition($plugin_id);
Read moreD8 Plugin discovery
Plugin discovery is the process by which Drupal finds plugins of a given type. A discovery method must be set for every plugin type (explained in the plugin manager documentation).
The discovery component of plugins implements a DiscoveryInterface that defines the methods any discovery class must have.
<?php
/**
* @file
* Contains \Drupal\Component\Plugin\Discovery\DiscoveryInterface.
*/
namespace Drupal\Component\Plugin\Discovery;
/**
* Defines the plugin discovery interface.
*/
interface DiscoveryInterface {
/**
* Gets a specific plugin definition.
*
* @param string $plugin_id
* A plugin id.
*
* @return array
* A plugin definition.
*/
public function getPluginDefinition($plugin_id);
/**
* Gets the definition of all plugins for this type.
*
* @return array
* An array of configuration definitions.
*/
public function getPluginDefinitions();
}
?>There are three different core discovery types.
- StaticDiscovery
D8 Plugin types (plugin managers)
The plugin manager is the central controlling class that defines how the plugins of a particular type will be discovered and instantiated. This class is called directly in any module wishing to invoke a plugin type.
This documentation will require an understanding of PSR-0.
Defining the Plugin Manager
There are only two requirements for defining a new plugin manager:
- You must define a discovery method.
- You must define a factory.
Everything else within the plugin system is situational and based upon your use case. For this plugin type, we will use the hook discovery and the default factory.
<?php
namespace Drupal\components\Plugin\Manager;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Core\Plugin\Discovery\HookDiscovery;
use Drupal\Component\Plugin\Factory\DefaultFactory;
/**
* Defines the plugin manager for Components plugins.
*/
class ComponentsPluginManagerBase extends PluginManagerBase {
/**
* Constructs a new Components plugin manager object.
*/
public function __construct() {
$this->discovery = new HookDiscovery('component_info');
$this->factory = new DefaultFactory($this);
}
}
?>Plugin API in Drupal 8
Why plugins?
TBD [see comment]
Overview:
The D8 plugin system provides a set of guidelines and reusable code components to allow developers to expose pluggable components within their code and (as needed) support managing these components through the user interface. The plugin system has three base elements:
-
Plugin Types
The plugin type is the central controlling class that defines how the plugins of this type will be discovered and instantiated. The type will describe the central purpose of all plugins of that type; e.g. cache backends, image actions, blocks, etc.
-
Plugin Discovery
Plugin Discovery is the process of finding plugins within the available code base that qualify for use within this particular plugin type's use case.
-
Plugin Factory
The Factory is responsible for instantiating the specific plugin(s) chosen for a given use case.