web-dev-qa-db-fra.com

Rendre par programme un bloc dans un modèle twig

J'ai besoin de rendre un bloc de vues dans mon modèle page.html.twig. En D7, je ferais ceci:

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

In Drupal 8 module_invoke est déconseillé et recommandé d'utiliser ceci: (j'ai ajouté le nom du bloc comme deuxième paramètre)

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

J'ai essayé quelques trucs. J'ai d'abord essayé de le faire dans un modèle twig mais je ne sais pas comment appeler les fonctions php dans un modèle twig, donc cela ne s'est pas avéré Trop bien.

Ensuite, j'ai appelé la fonction dans la fonction preprocess_page () du fichier .theme mais avant de pouvoir la faire fonctionner, j'ai essayé quelque chose de plus simple pour essayer de faire fonctionner une variable à l'intérieur du modèle twig qui n'a pas fonctionné) ne fonctionne pas non plus, par exemple:

Dans la fonction template_preprocess_page (& $ vars) du fichier .theme:

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

J'ai essayé d'appeler my_var dans le modèle twig mais cela n'a pas fonctionné et j'ai reçu un message d'erreur disant "Le site a une erreur, veuillez contacter l'administrateur"

Donc, pour résumer, voici mes questions:

  1. Comment puis-je rendre les variables disponibles dans les modèles twig?
  2. Comment appeler des fonctions dans les modèles twig?
  3. Dois-je rendre des blocs à l'intérieur du fichier .theme ou du modèle twig?
28
Rick Bergmann

Vous êtes sur la mauvaise voie avec module_invoke (). C'est juste une façon élégante d'appeler la fonction {$ module_name} _block_view ().

Le fait qu'il ait changé n'a pas d'importance, le fait est que le système de blocs a complètement changé en 8.x et utilise maintenant des plugins et des entités de configuration, ces fonctions n'existent plus.

Vous avez quelques options.

a) Réutilisez une entité de configuration de bloc existante et affichez-la. Très facile, mais nécessite que cette configuration existe, par ex. en tant que bloc désactivé.

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

b) Créez directement l'instance du plugin de bloc, passez-lui la configuration (vous pouvez trouver facilement l'ID et la configuration du plugin de bloc dans une entité de configuration de bloc exportée). L'inconvénient est que vous n'obtenez pas la mise en cache du rendu, mais si vous l'affichez quelque part qui est déjà mis en cache (comme un modèle de nœud), cela n'a pas vraiment d'importance.

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

c) Dans le cas d'une vue, vous pouvez également charger la vue directement et l'afficher.

d) Vous pouvez également repenser complètement votre approche et utiliser des régions de bloc ou Page Manager (qui utilise des plugins de bloc standard dans 8.x).

48
Berdir

Dans Drupal 8, cela fonctionne pour rendre un plugin de bloc (c'est-à-dire que vous avez créé dans un module personnalisé) dans 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();
}

Vous pouvez ensuite le rendre dans votre modèle twig comme ceci:

{{ content.custom_block_output }}

Remarque: cela chargera une version générique de votre bloc. Si vous voulez charger une instance de votre bloc avec des variables (après l'avoir créée dans/admin/structure/block), vous devez la charger de cette façon:

    // 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;
      }
    }
12
oknate

Vous pouvez utiliser Twig Tweak module pour cela, alors vous pouvez utiliser la syntaxe suivante:

  <dd>{{ drupal_block('myblock') }}</dd>

Connexes: Comment puis-je placer un bloc par programme?

6
kenorb