Call Us Today! (443) 500-7624
A world where things are available for you to use free of charge, is an ideal world, however if you don’t know how to use these tools to advance your purpose, you can be stuck at the same place for years, until you get up and go learn what it is that you need to learn; to be able to use the tools that you need, in order for you to accomplish your goals.
In today’s article, we are going to talk about Plugins in Drupal 8, we will focus first on Plugin Factories and Mapper and then we’ll talk about other aspects of the Plugin API. When a developer wants to instantiate a plugin and don’t know anything about how the plugin is handled, they can accomplish this by using the plugin factory.
Useful implementations of the FactoryInterface are provided by Drupal core, so that it can be used to instantiate plugin instances, through custom plugin managers. The MyPluginManager::createInstance()method is provided to the plugin manager. A plugin instance can be instantiated with this method because it proxies the request to the selected factory class which instantiate and return the specified plugin instance.
The \Drupal\Component\Plugin\Factory\FactoryInterface is implemented by the plugin factories. The most base factory in Drupal core is the default factory, which is provided by the Drupal\Component\Plugin\Factory\DefaultFactory class.
Questions such as What arguments should be passed to a class and which one should be instantiated? Are all answered by the default factory. By the way, this is not the default factory that Drupal uses, we’ll talk about the container factory next which is the one that Drupal uses as its default factory.
Once a plugin has been located and provided to the plugin manager, then the plugin factory maps that plugin ID to a class, then that class is returned after it has been instantiated with common arguments.
The definition of the plugin which is returned by the discovery mechanism, the ID of the plugin being instantiated and any additional information about configuration passed to the createInstance() method when it is called; are some of the arguments passed by the default factory.
An example code of this is: Note: All the code on this article is provided by drupilize.me
// Arguments passed to __construct() method:
// - $configuration (array): Passed to the createInstance() method from caller.
// - $plugin_id (string): Unique ID of the plugin being instantiated.
// - $plugin_definition (array): Plugin meta-data read from the annotation.
return new HamSandwich($configuration, $plugin_id, $plugin_definition);
The recommended factory for most use cases regardless of what the name may imply is known as the container factory. The
Drupal\Core\Plugin\Factory\ContainerFactory
class can do the same thing as the
Drupal\Component\Plugin\Factory\DefaultFactory
class; however, it has one major addition, once it has extended the DefaultFactory class. The ContainerFactory class performs constructor injection, and by calling the:: create() method, it can inject a copy of the Drupal services container for a module to use. If you want your custom plugin manager to have access to the services container, then you’ll want to use the ContainerFactory class. When a plugin does not use the container injection pattern or don’t implement the:: create() method, the container factory will be able to recognize that, and instead follows the Default DefaultFactory factory method to instantiate the plugin.
Whenever an instance of a plugin has the ability to decide, which factory it wants to use, then that factory method is the best choice, in this case, this is the ContainerFactory. A good example code is listed below.
/ Arguments passed to create() method:
// - $container: A copy of the Drupal service container.
// - $configuration (array): Passed to the createInstance() method from caller.
// - $plugin_id (string): Unique ID of the plugin being instantiated.
// - $plugin_definition (array): Plugin meta-data read from the annotation.
return CheeseSandwich::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
Another type of factory is the reflection factory, which is provided by the Drupal\Component\Plugin\Factory\ReflectionFactory class.
This factory is able to allow a variable or unknown set of arguments to be in the constructor of a plugin manager, which adds more flexibility to development efforts. Some introspection is done by this factory in the class it is about to instantiate; by analyzing the class. The list of arguments being passed to the constructor, based on the method signature to the constructor is also derived by this factory.
Thank you for reading this article!!!
\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!!!
Phone: (443) 500-7624
Email: admin@kinginfolife.com
Address: Baltimore, MD 21206
All Rights Reserved | KING INFO LIFE