Rendre un bloc par programmation dans un modèle de brindille

28

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']);
?>

Dans Drupal 8 module_invoke est obsolète 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 de brindille mais je ne sais pas comment appeler les fonctions php dans un modèle de brindille, donc cela ne s'est pas bien passé.

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 juste pour essayer de faire fonctionner une variable dans le modèle de brindille qui ne fonctionnait 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 à l'intérieur du modèle de brindille 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 rendre les variables disponibles dans les modèles de brindilles?
  2. Comment appeler des fonctions dans des modèles de brindilles?
  3. Dois-je rendre des blocs à l'intérieur du fichier .theme ou du modèle de brindille?
Rick Bergmann
la source

Réponses:

47

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 exemple 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).

Berdir
la source
Merci pour votre réponse. J'aimerais aller avec A ou B. Une région fonctionnera mais je veux éviter d'utiliser une région. Le seul problème que j'ai, c'est lorsque j'appelle block_output dans le modèle de brindille, j'ai une erreur - "Nom de balise inattendu" block_output ", donc je ne sais pas comment rendre cette variable disponible même si je l'ai créée dans la fonction preprocess_page. Je vais essayer de le
Rick Bergmann
On dirait que vous utilisez {%? Utilisez {{block_output}}.
Berdir
Oui, c'était ça! J'essaie toujours de comprendre la brindille. Merci.
Rick Bergmann
Depuis Drupal 8.0.0 entityManager est obsolète. Utilisez plutôt entityTypeManager .
Philipp Michael
où dois-je mettre ce code? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ variables ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Merci!
11

Dans Drupal 8, cela fonctionne pour le rendu d'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 de brindille comme ceci:

{{ content.custom_block_output }}

Remarque: cela chargera une version générique de votre bloc. Si vous souhaitez 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;
      }
    }
oknate
la source
1
C'était la solution pour moi et de loin la plus simple.
Guillaume Bois