Cómo manipular un Entity:Block via código en Drupal 8

Author Top
enzo

Este es mi primer post después de que Drupal 8 fuera liberado oficialmente, ahora es el momento de empezar a hablar de como hacer algunas cosas básicas utilizando Drupal 8.

Aunque he estado trabajando mucho con el core de Drupal 8, hay algunas cosas típicas que aun encuenro un poco extrañas. Pero ser honesto es más culpa mía que de Drupal 8; Todo lo que debemos hacer es ajustar un poco nuestros patrones mentales.

Hoy quiero mostrarles cómo trabajar con entidates de tipo Block en Drupal 8, porque ayer pasé varias horas tratando de entender cómo manipular un bloque  y así extender una funcionalidad para el proyecto Drupal console.

1. Obtener bloques.

Esto parece una tarea fácil, pero hay algunas consideraciones que debe tener en cuenta.

En primer lugar, ¿Necesito una lista de todos los bloques disponibles o todos los bloques habilitados?

¿Por qué esta separación es importante? Como tal vez ya sabesn Drupal 8 los bloques son plugins y utilizan anotaciones para exponer a Drupal 8 su existencia. Por lo tanto, podríamos obtener una lista de los bloques, pero no todos sera objectos del tipo Entity:Block, así que solo es posible obtener su definición, esto es importante porque no se puede manipular y sólo pueden ser utilizados como información extra en la lógica de tu código.

Sólo los bloques que están habilitados y asignados a un tema y en una región son entidades Entity:Block.

1.1 Obtener bloques disponibles.

Usar el servicio plugin.manager.block podremos todos las definiciones de bloque disponibles, como se puede apreciar en el siguiente extracto de código.

$blockManager = \Drupal::service('plugin.manager.block');
$contextRepository = \Drupal::service('context.repository');

// Get blocks definition
$definitions = $blockManager->getDefinitionsForContexts($contextRepository->getAvailableContexts());

print_r($definitions['help_block']);

Ejecutando el código anterior, tendriamos una salida para el bloque help_block similar al siguiente fragmento.

Array
(
    [admin_label] => Drupal\Core\StringTranslation\TranslatableMarkup Object
        (
            [string:protected] => Help
            [translatedMarkup:protected] =>
            [options:protected] => Array
                (
                )

            [stringTranslation:protected] =>
            [arguments:protected] => Array
                (
                )

        )

    [category] => Help
    [derivative] =>
    [id] => help_block
    [class] => Drupal\help\Plugin\Block\HelpBlock
    [provider] => help
)

Como se puede ver es una información valiosa sobre el bloque, pero no es una instancia real de Entity:Block.

1.2 Obtener una lista de bloques disponibles.

El uso la clase Drupal:EntityQuery, podemos construir una especie de consulta SQL para una entidad específica, en este caso para las entidades de tipo bloque. El siguiente fragmento de código obtiene la lista completa de identificadores de bloques disponibles.

$ids = \Drupal::entityQuery('block')->execute();

Por supuesto que podemos filtrar los resultados, por ejemplo, podríamos utilizar la condición plugin a buscar todos los bloque relacionado con el módulo de help, como se puede ver en el siguiente fragmento de código.

$ids = \Drupal::entityQuery('block')
    ->condition('plugin', 'help_block')
    ->execute();

print_r($ids);

Después de ejecutar el código anterior podríamos obtener una salida similar a la siguiente:

Array
(
    [bartik_help] => bartik_help
    [himalaya_help] => himalaya_help
    [seven_help] => seven_help
)

El resultado muestra en identificadores de Entity:Block, en relación con los tres temas que tengo habilitados en mi sistema Bartik, Seven e Himalaya.

2. Cargando un Entity:Block

Hasta ahora hemos obtenido definiciónes de bloques e iidentificadores Entity:Block, pero no un verdadero Entity:Block déjame mostrarte cómo hacerlo haciendo uso de la clase Drupal\block\Entity\Block como se puede ver a continuación.

use Drupal\block\Entity\Block;
$block = Block::load('bartik_help');
print_r($block);

El código anterior carga un Entity:Block para el id bartik_help, si se ejecuta este código en un módulo personalizado obtendrá una salida como la siguiente.

Drupal\block\Entity\Block Object
(
    [id:protected] => bartik_help
    [settings:protected] => Array
        (
            [id] => help_block
            [label] => Help
            [provider] => help
            [label_display] => 0
        )

    [region:protected] => content
    [weight:protected] => -30
    [plugin:protected] => help_block
    [visibility:protected] => Array
        (
        )
......
......
    [dependencies:protected] => Array
        (
            [module] => Array
                (
                    [0] => help
                )

            [theme] => Array
                (
                    [0] => bartik
                )

        )

    [provider] =>
)

3. Crear un Entity:Block

Por último, pero no menos importante, dejame mostraré cómo crear una Entity:Block usando su definición en código.

Imagína que haz creado un plugin bloque usando el proyecto Drupal Console con default_block como identificador, usando el siguient comando.

$ drupal generate:plugin:block

Si deseas habilitar ese bloque generado mediante código, puedes utilizar el siguiente fragmento de código.

$blockEntityManager = \Drupal::service('entity.manager')->getStorage('block');
$block = $blockEntityManager->->create(
  array(
      'id'=> $plugin_id,
      'plugin' => $plugin_id,
      'theme' => $theme
  )
);
$block->setRegion('content');
$block->save();

Además, he decidido asignar el bloque con id default_block dentro de la región content para el tema Bartik, después de crear la Entidad: Bloque.

Espero que hayas encontrado este artículo útil.