Community Documentation

Plugin API in Drupal 8

Last updated April 30, 2013. Created by EclipseGc on June 15, 2012.
Edited by claudiu.cristea, xjm, dixon_, Sylvain Lecoy. Log in to edit this page.

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:

  1. 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.

  2. 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.

  3. Plugin Factory

    The Factory is responsible for instantiating the specific plugin(s) chosen for a given use case.

Additionally, the plugin system includes several situationally useful components:

  • Plugin Derivatives

    Plugin Derivatives allow a single plugin to act in place of many. This is useful for situations where user entered data might have an impact on available plugins. For example, if menus are placed on screen using a plugin, then when the site administrator creates a new menu, that menu must be available for placement without needing a new plugin to do so. Plugin Derivatives also support the user interface by allowing it to display multiple plugins in place of one, allowing for help text specific to the use case to be rendered and utilized. The primary purpose of plugin derivatives is to provide partially configured plugins as "first class" plugins that are indistinguishable in the UI from other plugins, thus reducing the burden on administrators using these plugins.

  • Discovery Decorators

    A discovery decorator is another available discovery method meant to wrap an existing discovery method. Core currently supplies the cacheDecorator which will cache the discovery process that is chosen for a plugin type. This pattern could be expanded to other use cases if necessary.

  • Plugin Mappers

    Plugin Mappers allow you to map something (most often a string) to a specific plugin instance. Plugin types which use this approach can return fully configured and instantiated plugins based upon arbitrarily definable names instead of requiring developers using this api to manually instantiate and configure a plugin instance.

This document will give an in-depth discussion of all these concepts, with best practices and code examples.

Comments

Overview

It may be obvious for most developers but I think that an overview is needed. For somebody coming directly and trying to start developing for D8, without following previously the 8.x development process, it may not be clear what' the deal with plugins. Some questions just need answers:

  1. What are plugins? Why plugins?
  2. Pluging vs. Hooks: Explain why the actual module system (=< 7.x) cannot accomplish some needs
  3. Samples of pluggable components: past vs. future. Give at least one example of pluggable component in D7, how was implemented the plugin till now. How will be implemented the same feature in D8 using Plugin API. What are the benefits?

__________________
Claudiu Cristea
webikon.com
www.claudiucristea.ro

yes

We struggled with some of

We struggled with some of these questions, or rather, the answers to them early on, I think I can answer most of these fairly concisely, but it requires some Drupal development experience, otherwise it is without context. In those terms, I'm willing to attempt an answer, and we can backport that into the docs.

1.) What are plugins? Why plugins?

Plugin types are to Drupal essentially Object Oriented info hooks. When we dissect the typical info hook what we generally find is an informational procedural bit of code that usually implies some sort of relation to a bunch of other hooks. Taking hook_block_info() as an example we have hook_block_save, hook_block_view, and a number of other hooks as well. The plugin encapsulates all of these "block" hooks as methods of a block plugin and imparts to us all the benefits of an OO approach to that problem space.

2.) I think my answer in 1 effectively answers this too, but to be explicit: "There's nothing we're doing here that can't be accomplished in hooks beyond the typical OO constructs that aren't available to procedural functions (like inheritance of abstract classes and enforcement of methods being present)." In short, plugins are an OO replacement for info hooks and any hook associated with an info hook. At the same time, they provide a much more robust mechanism for replacement of logic, which is something we could not do previously. With plugins you can actually swap a class for a particular plugin and run completely different code than what core or a contrib module provided, which is incredibly useful.

3.) Again, I think I sort of began answering this already with my blocks example, but I'll dive in further.

Blocks used to have hook_block_info() and then a number of block hooks beyond that. When block info was replaced by the block plugin type, all of those block hooks became methods of the plugins representing each block. We build an abstract block class that provides sane defaults for all of the core provided blocks and their methods, and then block plugins only override the methods they specifically need to provide for. A good example of this is hook_block_view() vs BlockBase::blockBuild(). The blockBuild() method is going to look very similar to hook_block_view() (at least at this current stage of the D8 cycle) but each of these are in the class that is responsible for them instead of being in a module hook with a case statement looking at module/delta. At the same time, we got a hook_block_alter() function for modules to implement. This essentially replaces hook_block_info_alter() and goes further still allowing you to do more than just manipulate the data representing a give block or blocks in the UI. This hook allows you to actually swap out the class that runs a block, so you have complete control over the final product in this regard. Customization of a block can be done in MANY other ways, this is just the ultimate override in a sense and is one of the many advantages of using plugins.

I hope this at least starts to answer your questions more directly.

Eclipse

Eclipse
Drupal Evangelist

nobody click here