Drupal 8 Plugin API | Drupal 8

Drupal 8 Plugin API

Submitted by editor on Wed, 06/07/2017 - 19:55
Question

How to use drupal 8  Plugin API ?

Drupal 8 embedded with a plugin system. In drupal 8, Plugin is a group of PHP classes used for a defined specific usage. You can use any registered  plugins, add new plugins and also create your own plugin type.

This tutorial show how to create your own drupal 8 plugin type with your ows plugins manager.

Create a custom module.

(Here, the module name is 'mymodule'). Click here to know how to create a module.

Create Plugin interface.

(Here : FoodPluginInterface.php)
Example :
<?php
namespace Drupal\mymodule;
/**
 * This is the plugin interface, to define all plugins methods.
 */
interface FoodPluginInterface {
  /**
   * Get the plugin label.
   * @return string
   */
  public function label();
  /**
   * Return a text.
   * @return string
   */
  public function getText();
}

Create Annotation class.

(Here : Annotation/Food.php)
Example :
<?php
namespace Drupal\mymodule\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
 * Defines a Food annotation object.
 *
 * @ingroup food_api
 *
 * @Annotation
 */
class Food extends Plugin {
  /**
   * The plugin ID.
   *
   * @var string
   */
  public $id;
  /**
   * The administrative label of the block.
   *
   * @var \Drupal\Core\Annotation\Translation
   *
   * @ingroup plugin_translatable
   */
  public $admin_label = '';
}

Create Plugin Manager

(Here : FoodPluginManager.php) and use FoodPluginInterface and Annotation class.
Example :
<?php
namespace Drupal\mymodule\Plugin;
use Drupal\Component\Plugin\Factory\DefaultFactory;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
/**
 * Provides a Food plugin manager.
 */
class FoodPluginManager extends DefaultPluginManager {
  /**
   * Constructs a new FoodPluginManager object.
   */
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
    //parent::__construct('Plugin/Food', $namespaces, $module_handler, NULL, 'Drupal\mymodule\Annotation\Food');
    parent::__construct('Plugin/Food',$namespaces,$module_handler,'Drupal\mymodule\FoodPluginInterface','Drupal\mymodule\Annotation\Food');
    $this->alterInfo('food_info');
    $this->setCacheBackend($cache_backend, 'food_info_plugins');
    $this->factory = new DefaultFactory($this->getDiscovery());
  }
}

Create a plugin manager service.

(Here : plugin.manager.food in mymodule.services.yml) and use the FoodPluginManager
Example :
services:
  plugin.manager.food:
    class: Drupal\mymodule\Plugin\FoodPluginManager
    parent: default_plugin_manager

Now your plugin type is ready to use. To create plugins esily, we will use a PluginBase abstract class (Here : FoodBase) then extend this base class.
Example (Base class : FoodBase)
<?php
namespace Drupal\mymodule\Plugin;
use Drupal\Core\Plugin\PluginBase;
use Drupal\mymodule\FoodPluginInterface;
/**
 * Defines a base food plugin implementation that plugins will extend.
 *
 * @ingroup food_api
 */
abstract class FoodBase extends PluginBase implements FoodPluginInterface {
  /**
   * {@inheritdoc}
   */
  public function label() {
    $definition = $this->getPluginDefinition();
    return (string) $definition['admin_label'];
  }
}

Example: (Class: Bread.php)
<?php
namespace Drupal\mymodule\Plugin\Food;
use Drupal\mymodule\Plugin\FoodBase;
/**
 * Defines a fallback plugin for missing food plugins.
 *
 * @Food(
 *   id = "cake",
 *   admin_label = @Translation("Cake"),
 * )
 */
class Cake extends FoodBase {
  /**
   * Return a text.
   * @return string
   */
  public function getText() {
    return "This is Cake plugin";
  }
}

 

Usage / Use case.

Now using the plugins manager service, you can get and use all plugins of this type.
Example:
// Get all plugins of the type.
$type = \Drupal::service('plugin.manager.food');
$plugin_definitions = $type->getDefinitions();

// Get a specific type by ID.
\Drupal::service('plugin.manager.food')->getDefinition('cake');

// Finally, use the plugin.
$type = \Drupal::service('plugin.manager.food');
$plugin = $type->createInstance('cake');
$result = $plugin->getText();

// Note : You can also get the manager like:
$type = new FoodPluginManager(\Drupal::getContainer()->getParameter('container.namespaces'));

 

Drupal Tutorials:
https://www.drupal.org/docs/8/api/plugin-api/plugin-api-overview
https://www.drupal.org/docs/8/api/plugin-api/creating-your-own-plugin-manager

Add new comment