Programaticamente renderizar um bloco em um modelo de galho

28

Preciso renderizar um bloco de visualizações no meu modelo page.html.twig. Em D7 eu faria isso:

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

No Drupal 8 module_invoke está obsoleto e é recomendável usar isso: (adicionei o nome do bloco como o segundo parâmetro)

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

Eu tentei algumas coisas. Primeiro tentei fazê-lo em um modelo de galho, mas não sei como chamar funções php em um modelo de galho, de modo que não resultou muito bem.

Em seguida, chamei a função na função preprocess_page () no arquivo .theme, mas antes que eu pudesse funcionar, tentei algo mais simples, apenas para fazer uma variável funcionar dentro do modelo de galho que também não funcionava, por exemplo:

Na função template_preprocess_page (& $ vars) no arquivo .theme:

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

Tentei ligar para my_var dentro do modelo de galho, mas não funcionou e recebi uma mensagem de erro dizendo "O site está com um erro, entre em contato com o administrador"

Então, para resumir, aqui estão minhas perguntas:

  1. Como disponibilizo variáveis ​​dentro de modelos de galho?
  2. Como chamo funções dentro de modelos de galho?
  3. Eu renderizo blocos dentro do arquivo .theme ou modelo de galho?
Rick Bergmann
fonte

Respostas:

47

Você está no caminho errado com module_invoke (). Essa é apenas uma maneira elegante de chamar a função {$ module_name} _block_view ().

O fato de ter mudado não importa, o ponto é que o sistema de blocos mudou completamente no 8.x e agora está usando plugins e entidades de configuração, essas funções não existem mais.

Você tem poucas opções.

a) Reutilize uma entidade de configuração de bloco existente e visualize-a. Muito fácil, mas requer que essa configuração exista, por exemplo, como um bloco desativado.

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

b) Crie a instância do plug-in de bloco diretamente, passe a configuração (você pode encontrar o ID e a configuração do plug-in de bloco facilmente em uma entidade de configuração de bloco exportada). A desvantagem é que você não obtém o cache de renderização, mas se você o exibir em algum lugar que já esteja armazenado em cache (como um modelo de nó), isso realmente não importa.

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

c) No caso de uma vista, você também pode carregar a vista diretamente e exibi-la.

d) Você também pode repensar completamente sua abordagem e usar regiões de bloco ou o Page Manager (que usa plug-ins de bloco padrão no 8.x).

Berdir
fonte
Obrigado pela sua resposta. Eu gostaria de ir com A ou B. Uma região funcionará, mas quero evitar o uso de uma região. O único problema que estou tendo é que, quando chamo block_output no modelo twig, ocorre um erro - "Nome inesperado da tag" block_output ", para que eu não saiba como disponibilizar essa variável, mesmo que a tenha criado na função preprocess_page. vou tentar trabalhar com isso.
Rick Bergmann
Parece que você está usando {%? Use {{block_output}}.
Berdir 29/03/2015
Sim, foi isso! Ainda tentando pegar o jeito do galho. Obrigado.
21915 Rick Bergmann
Desde o Drupal 8.0.0, o entityManager está obsoleto. Use entityTypeManager .
Philipp Michael
onde coloco esse código? $ bloco = \ Drupal \ bloco \ Entidade \ Bloco :: load ('your_block_id'); $ variáveis ​​['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Obrigado!
11

No Drupal 8, isso funciona para renderizar um plug-in de bloco (ou seja, que você criou em um módulo personalizado) em um 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();
}

Você pode renderizá-lo em seu modelo de galho da seguinte forma:

{{ content.custom_block_output }}

Nota: isso carregará uma versão genérica do seu bloco. Se você deseja carregar uma instância do seu bloco com variáveis ​​(depois de criá-la em / admin / structure / block), você deve carregá-la desta maneira:

    // 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
fonte
1
Esta foi a solução para mim e de longe a mais fácil.
Guillaume Bois