Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
Showing
with 219 additions and 19 deletions
......@@ -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 https://drupal.org/developing/api/8/plugins 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 https://drupal.org/developing/api/8/plugins 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
* https://drupal.org/developing/api/8/plugins 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
*/
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment