Extender plugins de tipo bloque en Drupal

Extender plugins de tipo bloque en Drupal

Publish Date: May 25
0 0

Una de las cosas que más me gustán hacer en Drupal es crear una clase abstracta a modo de "base" cuando estoy definiendo bloques que se van a usar en un Slide.

En este caso como el Slide afectaba a la información de páginas de taxonomías de un vocabulario lo que hice fue crear una clase abstracta para definir todos los elementos comunes de todos los bloques.

<?php

declare(strict_types=1);

namespace Drupal\project_term_area_study\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\taxonomy\TermInterface;

/**
 * Base class for all blocks used in area of study taxonomy pages.
 */
abstract class AreaOfStudyBaseBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a new MyCustomBlockBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    private readonly EntityTypeManagerInterface $entity_type_manager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );
  }

  /**
   */
  protected function getTermContext(): ?TermInterface {
    $term = $this->getContextValue('taxonomy_term');

    if ($term instanceof TermInterface) {
      return $term;
    }
    return NULL;
  }

}
Enter fullscreen mode Exit fullscreen mode

Lo que ambos bloques que voy a usar comparten es que ambos necesitan el servicio entity_type.manager, y usan el contexto de bloques, en este caso para recuperar el término al que corresponde la página.

<?php

declare(strict_types=1);

namespace Drupal\project_term_area_study\Plugin\Block;

use Drupal\Core\Url;

/**
 * Provides an area study degree standard name list block.
 *
 * @Block(
 *   id = "project_term_area_study_degree_standard_name_list",
 *   admin_label = @Translation("Area study degree standard name list"),
 *   category = @Translation("project"),
 *   context_definitions = {
 *     "taxonomy_term" = @ContextDefinition("entity:taxonomy_term")
 *   }
 * )
 */
final class AreaOfStudyDegreeStandardNameListBlock extends AreaOfStudyBaseBlock {

  /**
   * {@inheritdoc}
   */
  public function build(): array {
    $term = $this->getTermContext();
  }

}
Enter fullscreen mode Exit fullscreen mode

En este caso no tenemos que volve a definir ni el constructor ni el método create para cargar los servicios definidos en la clase abstracta ya que son los mismos.

El segundo bloque necesita el servicio rendered, así que si se tiene que instanciar el constructor y el método create; lo importante también es que a parent::constructor además de los métodos por defecto de la base de plugins de Drupal se le tiene que pasar entityTypeManager que es un método que carga la clase abstracta que hemos definido.

<?php

declare(strict_types=1);

namespace Drupal\project_term_area_study\Plugin\Block;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\taxonomy\TermInterface;
use Drupal\views\Views;
use Drupal\Core\Render\RendererInterface;

/**
 * Provides an area of study - others area of study block.
 *
 * @Block(
 *   id = "project_term_area_study_others_area_of_study",
 *   admin_label = @Translation("Area of study - others area of study"),
 *   category = @Translation("project"),
 *   context_definitions = {
 *     "taxonomy_term" = @ContextDefinition("entity:taxonomy_term")
 *   }
 * )
 */
final class AreaOfStudyOthersAreaOfStudyBlock extends AreaOfStudyBaseBlock {

  /**
   * The current renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Constructs the plugin instance.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    EntityTypeManagerInterface $entityTypeManager,
    RendererInterface $renderer,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entityTypeManager);
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
    return new self(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('renderer'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build(): array {
    $term = $this->getTermContext();

  }

  /**
   */
  protected function getListOfTerms(TermInterface $term) :?array {
// Code here.
  }

  /**
   */
  private function renderViewContent(string $view_id, string $display_id, $arguments): mixed {
// Code here.
  }

}

Enter fullscreen mode Exit fullscreen mode

También es importante que aunque el método getTermContext() lo hemos definido en la clase abstracta en ambos bloques se tiene que definir dentro del "@block" para que Drupal pueda cargar el contexto.

Comments 0 total

    Add comment