Drupal 8 is a Great Way of Developing a Useful and Valuable Website - Part Seventeen

feature-top

Website developers must continue to develop and sharpen their skills, for them to have an edge in this very competitive world. In today’s article, we will continue our conversation about  Plugins in Drupal 8 so that we can implement one and know how to use them.

A module developer should be using the Drupal console to do his/her development in Drupal 8 because that’s the Drupalize.me way. Common plugin types can be found through Drupal console’s commands, that developers can generate. If a developer would like to see a list of plugins that the Drupal console can generate, he/she can simply type the code below.

drupal list generate: plugin

You won’t have to deal with a lot of pertinent redundant code, that can be simply generated for you, and you can focus on development.  A developer can also use an existing plugin and rename a few things to avoid boilerplate code. A developer should also know what plugin manager class is responsible for, and which plugin type, once he/she has a list of them, wants to use.

The plugin manager will define a new plugin so that it can be listed and instances of the plugin of the defined type can be instantiated. The way that plugins of a type are discovered and instantiated is defined by the central controlling class known as the plugin manager.

Any developer who wishes to invoke a plugin of any type can do so calling the plugin manager class directly inside of a module. A new plugin type can be created, by creating a new plugin manager. The place where the metadata of a single plugin instance is defined, as well as the method that will be used, for plugin discovery, is determined by plugin managers.

The following code:

\Drupal\Component\Plugin\PluginManagerInterface,

Implements all plugin managers, and this piece of code extends these three pieces of code, which are the basis for any new plugin manager.


\Drupal\Component\Plugin\Discovery\DiscoveryInterface, 
\Drupal\Component\Plugin\Factory\FactoryInterface and,
\Drupal\Component\Plugin\Mapper\MapperInterface.

The plugin.manager.*. a piece of code is used to generate plugin manager services and from the service container, a copy of the plugin manager can be requested. Example:

$example_manager = \Drupal::service('plugin.manager.example');

Once a developer has identified the plugin manager needed, to complete a task, then that developer has to start, by locating the name of the plugin manager service he/she needs. The controller will be the place where, a developer can inject their plugin manager services, and this is the Drupal way of doing things.

The code below is a controller file, located under custom_module/src/Controller, it is very important that you get those names and file directory correct, for Drupal to recognize your controller and plugin.

 

<?php

namespace Drupal\plugin_type_example\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\plugin_type_example\SandwichPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Controller for our example pages.
 */
class PluginTypeExampleController extends ControllerBase {
  /**
   * The sandwich plugin manager.
   *
   * We use this to get all of the sandwich plugins.
   *
   * @var \Drupal\plugin_type_example\SandwichPluginManager
   */
  protected $sandwichManager;
  /**
   * Constructor.
   *
   * @param \Drupal\plugin_type_example\SandwichPluginManager $sandwich_manager
   *   The sandwich plugin manager service. We're injecting this service so that
   *   we can use it to access the sandwich plugins.
   */
  public function __construct(SandwichPluginManager $sandwich_manager) {
    $this->sandwichManager = $sandwich_manager;
  } 
  /**
   * {@inheritdoc}
   *
   * Override the parent method so that we can inject our sandwich plugin
   * manager service into the controller.
   *
   * For more about how dependency injection works read https://www.drupal.org/node/2133171
   */
  public static function create(ContainerInterface $container) {
    // Inject the plugin.manager.sandwich service that represents our plugin
    // manager as defined in the plugin_type_example.services.yml file.
    return new static($container->get('plugin.manager.sandwich'));
  }
}

All defined plugins have information that can aid our application development to move forward faster. All that information from defined plugins is available to developers when they can make calls to the getDefinitions() method.

Enabled modules, can be used to locate all plugin definitions of the type in question, through the discovery handler. When the discovery handler is not used to retrieve data, then the DefaultPluginManager is used to retrieve the data from the cache if the data is available there. A good example of is in the code below, watch how the definitions of a plugin can be obtained in the code.

// Get the list of all the sandwich plugins defined on the system from the
// plugin manager. Note that at this point, what we have is *definitions* of
// plugins, not the plugins themselves.
$sandwich_plugin_definitions = $this->sandwichManager->getDefinitions();
// Let's output a list of the plugin definitions we now have.
$items = array();
foreach ($sandwich_plugin_definitions as $sandwich_plugin_definition) {
  // Here we use various properties from the plugin definition. These values
  // are defined in the annotation at the top of the plugin class: see
  // \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich.
  $items[] = t("@id (calories: @calories, description: @description )", array(
    '@id' => $sandwich_plugin_definition['id'],
    '@calories' => $sandwich_plugin_definition['calories'],
    '@description' => $sandwich_plugin_definition['description'],
  ));
}
// Add our list to the render array.
$build['plugin_definitions'] = array(
  '#theme' => 'item_list',
  '#title' => 'Sandwich plugin definitions',
  '#items' => $items,
);

When a list of plugin types is desired by a developer he/she may want to use the method above to accomplish this task. The unique ID of a plugin can be utilized in order to retrieve the definition of the plugin in question, calling the getDefinition($plugin_id) method.

// If we want just a single plugin definition, we can use getDefinition().
// This requires us to know the ID of the plugin we want. This is set in the
// annotation on the plugin class: see \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich.
$ham_sandwich_plugin_definition = $this->sandwichManager->getDefinition('meatball_sandwich');

In order to instantiate and use an individual plugin object, the  createInstance($plugin_id)  method can be used. It is not good practice to instantiate a plugin object directly, instead, the plugin manager should be used to do so. Understanding how instances of a plugin are created requires that you see it in action, in the code below.

// To get an instance of a plugin, we call createInstance() on the plugin
// manager, passing the ID of the plugin we want to load. Let's output a
// list of the plugins by loading an instance of each plugin definition and
// collecting the description from each.
$items = array();
// The array of plugin definitions is keyed by plugin id, so we can just use
// that to load our plugin instances.
$sandwich_plugin_definitions = $this->sandwichManager->getDefinitions();
foreach ($sandwich_plugin_definitions as $plugin_id => $sandwich_plugin_definition) {
  // We now have a plugin instance. From here on it can be treated just as
  // any other object; have its properties examined, methods called, etc.
  $plugin = $this->sandwichManager->createInstance($plugin_id);
  $items[] = $plugin->description();
}

All the code on this tutorial was taken from Drupalize.me.

 

Thank you for reading this article!!!

feature-top
feature-top

Add a Comment

Hernando Cadet

Hi every one, I obtained a bachelor's degree in Bioinformatics back in 2006, from Claflin University, after I received my bachelor's degree, I gained full time employment as a software engineer at a Video Relay Service company, maintaining databases and developing software for a new developed device called the VPAD.

I worked at that company for two years, then I became a web developer, and worked for a magazine for three years. After that job, I worked as a Drupal web developer, as a subcontractor for the NIH, for a year and then left the job to go back to school.

Hernando Cadet

Collaboratively administrate empowered markets via plug-and-play networks. Dynamically procrastinate B2C users after installed base benefits. Dramatically visualize customer directed convergence without

Collaboratively administrate empowered markets via plug-and-play networks. Dynamically procrastinate B2C users after installed base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.