Programáticamente un bloque en una plantilla de ramita

28

Necesito representar un bloque de vistas en mi plantilla page.html.twig. En D7 haría esto:

<?php
  $block = module_invoke('module_name', 'block_view', 'block_delta');
  print render($block['content']);
?>

En Drupal 8 module_invoke está en desuso y se recomienda usar esto: (he agregado el nombre del bloque como segundo parámetro)

Drupal::moduleHandler()->invoke($block, 'views_block__blog_block_1', $args = array());

Intenté algunas cosas. Primero intenté hacerlo en una plantilla de ramita, pero no sé cómo llamar a las funciones de php en una plantilla de ramita, por lo que no resultó demasiado bien.

Luego llamé a la función en la función preprocess_page () en el archivo .theme, pero antes de que pudiera funcionar, intenté algo más simple solo para intentar hacer que una variable funcionara dentro de la plantilla de ramita que tampoco funcionó, por ejemplo:

En la función template_preprocess_page (& $ vars) en el archivo .theme:

$test = 'Hello World';
$vars['$my_var'] = $test;

Intenté llamar a my_var dentro de la plantilla de ramita pero no funcionó y recibí un mensaje de error que decía "El sitio tiene un error, comuníquese con el administrador"

Entonces, para resumir, aquí están mis preguntas:

  1. ¿Cómo hago disponibles las variables dentro de las plantillas de ramita?
  2. ¿Cómo llamo a funciones dentro de plantillas de ramita?
  3. ¿Renderizo bloques dentro del archivo .theme o plantilla de ramita?
Rick Bergmann
fuente

Respuestas:

47

Estás en el camino equivocado con module_invoke (). Esa es solo una forma elegante de llamar a la función {$ module_name} _block_view ().

El hecho de que haya cambiado no importa, el punto es que el sistema de bloques cambió completamente en 8.xy ahora está usando complementos y entidades de configuración, esas funciones ya no existen.

Tienes pocas opciones.

a) Reutilice una entidad de configuración de bloque existente y visualícela. Muy fácil, pero requiere que exista esa configuración, por ejemplo, como un bloque deshabilitado.

$block = \Drupal\block\Entity\Block::load('your_block_id');
$variables['block_output'] = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);

b) Cree la instancia del complemento de bloque directamente, páselo a la configuración (puede encontrar la identificación y la configuración del complemento de bloque fácilmente en una entidad de configuración de bloque exportada). La desventaja es que no obtiene el almacenamiento en caché de renderizado, pero si lo muestra en algún lugar que ya está en caché (como una plantilla de nodo), eso realmente no importa.

$variables['block_output'] = \Drupal::service('plugin.manager.block')
  ->createInstance($plugin, $configuration)
  ->build();

c) En el caso de una vista, también puede cargar la vista directamente y mostrarla.

d) También puede repensar su enfoque por completo y usar regiones de bloque o Administrador de páginas (que usa complementos de bloque estándar en 8.x).

Berdir
fuente
Gracias por su respuesta. Me gustaría ir con A o B. Una región funcionará pero quiero evitar usar una región. El único problema que tengo es que cuando llamo a block_output en la plantilla de ramita, aparece un error: "Nombre de etiqueta inesperado" block_output ", así que no sé cómo hacer que esa variable esté disponible aunque la creé en la función preprocess_page. Trataré de resolverlo.
Rick Bergmann
Parece que estás usando {%? Use {{block_output}}.
Berdir
Sí, eso fue todo! Todavía estoy tratando de dominar la ramita. Gracias.
Rick Bergmann
Desde Drupal 8.0.0 entityManager está en desuso. Utilice entityTypeManager en su lugar.
Philipp Michael
¿Dónde pongo este código? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ variables ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); ¡Gracias!
11

En Drupal 8, esto funciona para representar un complemento de bloque (es decir, uno que haya creado en un módulo personalizado) en un preprocess_hook:

function mymodule_preprocess_something(array &$variables) {
  $customblock = \Drupal::service('plugin.manager.block')->createInstance('my_custom_block', []);
  $variables['content']['custom_block_output'] = $customblock->build();
}

Luego puede renderizarlo en su plantilla de ramita de esta manera:

{{ content.custom_block_output }}

Nota: esto cargará una versión genérica de su bloque. Si desea cargar una instancia de su bloque con variables (después de haberlo creado en / admin / structure / block), debe cargarlo de esta manera:

    // Load Instance of custom block with variables
    $example_block = \Drupal::entityManager()->getStorage('block')->load('example_block_machine_name');
    if (!empty($example_block)){
      $example_block_content = \Drupal::entityManager()
        ->getViewBuilder('block')
        ->view($example_block);
      if ($example_block_content) {
        // Add block content to build array
        $variables['content']['custom_block_output'] = $example_block_content;
      }
    }
oknate
fuente
1
Esta fue la solución para mí y, con mucho, la más fácil.
Guillaume Bois