Commit 4809d4d9 authored by Angie Byron's avatar Angie Byron
Browse files

Issue #2234439 by jhodgdon, cosmicdreams, xjm: Add a section for the plugin...

Issue #2234439 by jhodgdon, cosmicdreams, xjm: Add a section for the plugin system to the API doc landing page.
parent e5b3f93a
......@@ -18,6 +18,8 @@
* of a class to be located with the class itself, rather than in module-based
* info hooks.
* @ingroup plugin_api
* @Annotation
class Plugin implements AnnotationInterface {
......@@ -9,6 +9,8 @@
* Provides an interface for a configurable plugin.
* @ingroup plugin_api
interface ConfigurablePluginInterface {
......@@ -14,6 +14,8 @@
* Context aware plugins can specify an array of context definitions keyed by
* context name at the plugin definition under the "context" key.
* @ingroup plugin_api
interface ContextAwarePluginInterface extends PluginInspectionInterface {
......@@ -9,6 +9,8 @@
* Plugin interface for derivative plugin handling.
* @ingroup plugin_api
interface DerivativeInterface {
......@@ -10,6 +10,8 @@
* An interface defining the minimum requirements of building a plugin
* discovery component.
* @ingroup plugin_api
interface DiscoveryInterface {
......@@ -9,6 +9,8 @@
* Defines an object which stores multiple plugin instances to lazy load them.
* @ingroup plugin_api
abstract class PluginBag implements \Iterator, \Countable {
......@@ -11,6 +11,8 @@
* This interface provides some simple tools for code receiving a plugin to
* interact with the plugin system.
* @ingroup plugin_api
interface PluginInspectionInterface {
......@@ -26,6 +26,8 @@
* class, which contains the proxying logic.
* @see \Drupal\Component\Plugin\PluginManagerBase
* @ingroup plugin_api
interface PluginManagerInterface extends DiscoveryInterface, FactoryInterface, MapperInterface {
......@@ -11,6 +11,8 @@
* Provides an interface for an object utilizing a plugin bag.
* @see \Drupal\Component\Plugin\PluginBag
* @ingroup plugin_api
interface EntityWithPluginBagsInterface extends EntityInterface {
......@@ -9,6 +9,8 @@
* An interface for executable plugins.
* @ingroup plugin_api
interface ExecutableInterface {
......@@ -23,6 +23,8 @@
* Base class for plugin managers.
* @ingroup plugin_api
class DefaultPluginManager extends PluginManagerBase implements PluginManagerInterface, CachedDiscoveryInterface {
......@@ -13,6 +13,8 @@
* Base class for plugins supporting metadata inspection and translation.
* @ingroup plugin_api
abstract class PluginBase extends ComponentPluginBase {
use StringTranslationTrait;
......@@ -9,6 +9,8 @@
* Provides an interface for a plugin that contains a form.
* @ingroup plugin_api
interface PluginFormInterface {
......@@ -551,12 +551,7 @@ function search_mark_for_reindex($type, $sid) {
* data. Most of the system is handled by the Search module, so this must be
* enabled for all of the search features to work.
* To be discovered, the plugins must implement
* \Drupal\search\Plugin\SearchInterface and be annotated as
* \Drupal\search\Annotation\SearchPlugin plugins. Defining a plugin will allow
* administrators to set up one or more search pages using this plugin.
* There are three ways to interact with the search system:
* There are two ways to interact with the search system:
* - Specifically for searching nodes, you can implement
* hook_node_update_index() and hook_node_search_result(). However, note that
* the search system already indexes all visible output of a node; i.e.,
......@@ -569,12 +564,16 @@ function search_mark_for_reindex($type, $sid) {
* Each of these corresponds to a tab on the /search page, which can be
* used to perform searches. You will also need to implement the execute()
* method from the interface to perform the search. A base class is provided
* in \Drupal\search\Plugin\SearchPluginBase.
* in \Drupal\search\Plugin\SearchPluginBase. For more information about
* plugins, see the @link plugin_api Plugin API topic. @endlink
* If your module needs to provide a more complicated search form, then you
* need to implement it yourself. In that case, you may wish to define it as a
* local task (tab) under the /search page (e.g. /search/mymodule) so that users
* can easily find it.
* @see plugin_api
* @see annotation
......@@ -41,6 +41,7 @@
* @section other_essentials Other essential APIs
* - @link plugin_api Plugins @endlink
* - @link i18n Internationalization @endlink
* - @link cache Caching @endlink
* - @link utility Utility classes and functions @endlink
......@@ -287,7 +288,7 @@
* @section define Defining an entity type
* Entity types are defined by modules, using Drupal's Plugin API (see the
* @link plugins Plugin API topic @endlink for more information about plugins
* @link plugin_api Plugin API topic @endlink for more information about plugins
* in general). Here are the steps to follow to define a new entity type:
* - Choose a unique machine name, or ID, for your entity type. This normally
* starts with (or is the same as) your module's machine name. It should be
......@@ -986,7 +987,7 @@
* See the @link hooks Hooks topic @endlink for more information.
* - Plugins: Classes that a module defines, which are discovered and
* instantiated at specific times to add functionality. See the
* @link plugins Plugin API topic @endlink for more information.
* @link plugin_api Plugin API topic @endlink for more information.
* - Entities: Special plugins that define entity types for storing new types
* of content or configuration in Drupal. See the
* @link entity_api Entity API topic @endlink for more information.
......@@ -1001,17 +1002,189 @@
* @defgroup plugins Plugin API
* @defgroup plugin_api Plugin API
* @{
* Overview of the Plugin API
* Using the Plugin API
* @todo write this
* Additional documentation paragraphs need to be written, and functions,
* classes, and interfaces need to be added to this topic.
* @section sec_overview Overview and terminology
* The basic idea of plugins is to allow a particular module or subsystem of
* Drupal to provide functionality in an extensible, object-oriented way. The
* controlling module or subsystem defines the basic framework (interface) for
* the functionality, and other modules can create plugins (implementing the
* interface) with particular behaviors. The controlling module instantiates
* existing plugins as needed, and calls methods to invoke their functionality.
* Examples of functionality in Drupal Core that use plugins include: the block
* system (block types are plugins), the entity/field system (entity types,
* field types, field formatters, and field widgets are plugins), the image
* manipulation system (image effects and image toolkits are plugins), and the
* search system (search page types are plugins).
* Plugins are grouped into plugin types, each generally defined by an
* interface. Each plugin type is managed by a plugin manager service, which
* uses a plugin discovery method to discover provided plugins of that type and
* instantiate them using a plugin factory.
* Some plugin types make use of the following concepts or components:
* - Plugin derivatives: Allows a single plugin class to present itself as
* multiple plugins. Example: the Menu module provides a block for each
* defined menu via a block plugin derivative.
* - Plugin mapping: Allows a plugin class to map a configuration string to an
* instance, and have the plugin automatically instantiated without writing
* additional code.
* - Plugin bags: Provide a way to lazily instantiate a set of plugin
* instances from a single plugin definition.
* There are several things a module developer may need to do with plugins:
* - Define a completely new plugin type: see @ref sec_define below.
* - Create a plugin of an existing plugin type: see @ref sec_create below.
* - Perform tasks that involve plugins: see @ref sec_use below.
* See for more detailed
* documentation on the plugin system. There are also topics for a few
* of the many existing types of plugins:
* - @link block_api Block API @endlink
* - @link entity_api Entity API @endlink
* - @link field Various types of field-related plugins @endlink
* - @link views_plugins Views plugins @endlink (has links to topics covering
* various specific types of Views plugins).
* - @link search Search page plugins @endlink
* @section sec_define Defining a new plugin type
* To define a new plugin type:
* - Define an interface for the plugin. This describes the common set of
* behavior, and the methods you will call on each plugin class that is
* instantiated. Usually this interface will extend one or more of the
* following interfaces:
* - \Drupal\Component\Plugin\PluginInspectionInterface
* - \Drupal\Component\Plugin\ConfigurablePluginInterface
* - \Drupal\Component\Plugin\ContextAwarePluginInterface
* - \Drupal\Core\Plugin\PluginFormInterface
* - \Drupal\Core\Executable\ExecutableInterface
* - (optional) Create a base class that provides a partial implementation of
* the interface, for the convenience of developers wishing to create plugins
* of your type. The base class usually extends
* \Drupal\Core\Plugin\PluginBase, or one of the base classes that extends
* this class.
* - Choose a method for plugin discovery, and define classes as necessary.
* See @ref sub_discovery below.
* - Create a plugin manager/factory class and service, which will discover and
* instantiate plugins. See @ref sub_manager below.
* - Use the plugin manager to instantiate plugins. Call methods on your plugin
* interface to perform the tasks of your plugin type.
* - (optional) If appropriate, define a plugin bag. See @ref sub_bag below
* for more information.
* See and links therein for
* references. This should be an overview and link to details.
* @subsection sub_discovery Plugin discovery
* Plugin discovery is the process your plugin manager uses to discover the
* individual plugins of your type that have been defined by your module and
* other modules. Plugin discovery methods are classes that implement
* \Drupal\Component\Plugin\Discovery\DiscoveryInterface. Most plugin types use
* one of the following discovery mechanisms:
* - Annotation: Plugin classes are annotated and placed in a defined namespace
* subdirectory. Most Drupal Core plugins use this method of discovery.
* - Hook: Plugin modules need to implement a hook to tell the manager about
* their plugins.
* - YAML: Plugins are listd in YAML files. Drupal Core uses this method for
* discovering local tasks and local actions. This is mainly useful if all
* plugins use the same class, so it is kind of like a global derivative.
* - Static: Plugin classes are registered within the plugin manager class
* itself. Static discovery is only useful if modules cannot define new
* plugins of this type (if the list of available plugins is static).
* It is also possible to define your own custom discovery mechanism or mix
* methods together. And there are many more details, such as annotation
* decorators, that apply to some of the discovery methods. See
* for more details.
* The remainder of this documentation will assume Annotation-based discovery,
* since this is the most common method.
* @subsection sub_manager Defining a plugin manager class and service
* To define an annotation-based plugin manager:
* - Choose a namespace subdirectory for your plugin. For example, search page
* plugins go in directory Plugin/Search under the module namespace.
* - Define an annotation class for your plugin type. This class should extend
* \Drupal\Component\Annotation\Plugin, and for most plugin types, it should
* contain member variables corresponding to the annotations plugins will
* need to provide. All plugins have at least $id: a unique string
* identifier.
* - Define an alter hook for altering the discovered plugin definitions. You
* should document the hook in a *.api.php file.
* - Define a plugin manager class. This class should implement
* \Drupal\Component\Plugin\PluginManagerInterface; most plugin managers do
* this by extending \Drupal\Core\Plugin\DefaultPluginManager. If you do
* extend the default plugin manager, the only method you will probably need
* to define is the class constructor, which will need to call the parent
* constructor to provide information about the annotation class and plugin
* namespace for discovery, set up the alter hook, and possibly set up
* caching. See classes that extend DefaultPluginManager for examples.
* - Define a service for your plugin manager. See the
* @link container Services topic for more information. @endlink Your service
* definition should look something like this, referencing your manager
* class and the parent (default) plugin manager service to inherit
* constructor arguments:
* @code
* plugin.manager.mymodule:
* class: Drupal\mymodule\MyPluginManager
* parent: default_plugin_manager
* @endcode
* - If your plugin is configurable, you will also need to define the
* configuration schema and possibly a configuration entity type. See the
* @link config_api Configuration API topic @endlink for more information.
* @subsection sub_bag Defining a plugin bag
* Some configurable plugin types allow administrators to create zero or more
* instances of each plugin, each with its own configuration. For example,
* a single block plugin can be configured several times, to display in
* different regions of a theme, with different visibility settings, a
* different title, or other plugin-specific settings. To make this possible,
* a plugin type can make use of what's known as a plugin bag.
* A plugin bag is a class that extends \Drupal\Component\Plugin\PluginBag or
* one of its subclasses; there are several examples in Drupal Core. If your
* plugin type uses a plugin bag, it will usually also have a configuration
* entity, and the entity class should implement
* \Drupal\Core\Entity\EntityWithPluginBagsInterface. Again,
* there are several examples in Drupal Core; see also the
* @link config_api Configuration API topic @endlink for more information about
* configuration entities.
* @section sec_create Creating a plugin of an existing type
* Assuming the plugin type uses annotation-based discovery, in order to create
* a plugin of an existing type, you will be creating a class. This class must:
* - Implement the plugin interface, so that it has the required methods
* defined. Usually, you'll want to extend the plugin base class, if one has
* been provided.
* - Have the right annotation in its documentation header. See the
* @link annotation Annotation topic @endlink for more information about
* annotation.
* - Be in the right plugin namespace, in order to be discovered.
* Often, the easiest way to make sure this happens is to find an existing
* example of a working plugin class of the desired type, and copy it into your
* module as a starting point.
* You can also create a plugin derivative, which allows your plugin class
* to present itself to the user interface as multiple plugins. To do this,
* in addition to the plugin class, you'll need to create a separate plugin
* derivative class implementing
* \Drupal\Component\Plugin\Derivative\DerivativeInterface. The classes
* \Drupal\system\Plugin\Block\SystemMenuBlock (plugin class) and
* \Drupal\system\Plugin\Derivative\SystemMenuBlock (derivative class) are a
* good example to look at.
* @sec sec_use Performing tasks involving plugins
* Here are the steps to follow to perform a task that involves plugins:
* - Locate the machine name of the plugin manager service, and instantiate the
* service. See the @link container Services topic @endlink for more
* information on how to do this.
* - On the plugin manager class, use methods like getDefinition(),
* getDefinitions(), or other methods specific to particular plugin managers
* to retrieve information about either specific plugins or the entire list of
* defined plugins.
* - Call the createInstance() method on the plugin manager to instantiate
* individual plugin objects.
* - Call methods on the plugin objects to perform the desired tasks.
* @see annotation
* @}
......@@ -12,7 +12,8 @@
* Views plugins are objects that are used to build and render the view.
* Plugins are registered by extending one of the Views base plugin classes
* and defining settings in the plugin annotation.
* and defining settings in the plugin annotation. For more information about
* plugins, see the @link plugin_api Plugin API topic. @endlink
* Views has the following types of plugins:
* - Access: Access plugins are responsible for controlling access to the
......@@ -83,7 +84,6 @@
* \Drupal\views\Plugin\views\style\StylePluginBase.
* @todo Add an explanation for each type of handler.
* @todo Document how to use annotations and what goes in them.
* @todo Add @ingroup to all the base plugins for this group.
* @todo Add a separate @ingroup for all plugins?
* @todo Document specific options on the appropriate plugin base classes.
......@@ -91,6 +91,8 @@
* @see \Drupal\views\Plugin\views\PluginBase
* @see \Drupal\views\Plugin\views\HandlerBase
* @see plugin_api
* @see annotation
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment