Programowo renderuj blok w szablonie gałązki

28

Muszę wyrenderować blok wyświetleń w szablonie page.html.twig. W D7 zrobiłbym to:

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

W Drupal 8 module_invoke jest przestarzałe i zalecane jest użycie tego: (Dodałem nazwę bloku jako drugi parametr)

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

Próbowałem kilku rzeczy. Najpierw próbowałem to zrobić w szablonie gałązki, ale nie wiem, jak wywoływać funkcje php w szablonie gałązki, więc nie wyszło to zbyt dobrze.

Następnie wywołałem funkcję w funkcji preprocess_page () w pliku .theme, ale zanim udało mi się ją uruchomić, próbowałem czegoś prostszego, po prostu próbując sprawić, by zmienna działała w szablonie gałązki, która też nie działała, na przykład:

W funkcji template_preprocess_page (& $ vars) w pliku .theme:

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

Próbowałem zadzwonić do my_var w szablonie gałązki, ale to nie zadziałało i otrzymałem komunikat o błędzie „Witryna ma błąd, skontaktuj się z administratorem”

Podsumowując, oto moje pytania:

  1. Jak udostępnić zmienne w szablonach gałązek?
  2. Jak wywoływać funkcje w szablonach gałązek?
  3. Czy renderuję bloki w pliku .theme lub szablonie gałązki?
Rick Bergmann
źródło

Odpowiedzi:

47

Jesteś na niewłaściwym torze dzięki module_invoke (). To tylko fantazyjny sposób wywoływania funkcji {$ module_name} _block_view ().

Fakt, że się zmienił, nie ma znaczenia, chodzi o to, że system bloków zmienił się całkowicie w wersji 8.x i teraz używa wtyczek i encji konfiguracyjnych, funkcje te już nie istnieją.

Masz kilka opcji.

a) Ponownie użyj istniejącej jednostki konfiguracji bloku i wyświetl ją. Bardzo łatwe, ale wymaga takiej konfiguracji, np. Jako wyłączony blok.

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

b) Utwórz bezpośrednio instancję wtyczki blokowej, przekaż jej konfigurację (możesz łatwo znaleźć identyfikator wtyczki bloku i konfigurację w wyeksportowanej jednostce konfiguracji bloku). Minusem jest to, że nie dostajesz buforowania renderowania, ale jeśli wyświetlisz go gdzieś, który jest już buforowany (np. Szablon węzła), to tak naprawdę nie ma znaczenia.

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

c) W przypadku widoku można również załadować widok bezpośrednio i wyświetlić go.

d) Możesz także całkowicie przemyśleć swoje podejście i użyć regionów bloków lub Page Managera (który używa standardowych wtyczek blokowych w wersji 8.x).

Berdir
źródło
Dziękuję za Twoją odpowiedź. Chciałbym wybrać A lub B. Region będzie działał, ale chcę uniknąć korzystania z regionu. Jedyny problem, jaki mam, to to, że kiedy wywołuję block_output w szablonie gałązki, mam błąd - „Nieoczekiwana nazwa znacznika„ block_output ”, więc nie wiem, jak udostępnić tę zmienną, mimo że utworzyłem ją w funkcji preprocess_page. Spróbuję to wypracować
Rick Bergmann,
Wygląda na to, że używasz {%? Użyj {{block_output}}.
Berdir
Tak, to było to! Wciąż próbuję złapać gałązkę. Dzięki.
Rick Bergmann
Ponieważ Drupal 8.0.0 entityManager jest przestarzały. Zamiast tego użyj encjiTypeManager .
Philipp Michael
gdzie mam umieścić ten kod? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ zmienne ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Dziękuję Ci!
11

W Drupal 8 działa to w przypadku renderowania wtyczki blokowej (tzn. Utworzonej w niestandardowym module) w haku 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();
}

Następnie możesz wyrenderować go w szablonie gałązki w następujący sposób:

{{ content.custom_block_output }}

Uwaga: spowoduje to załadowanie ogólnej wersji twojego bloku. Jeśli chcesz załadować wystąpienie swojego bloku zmiennymi (po utworzeniu go w / admin / structure / block), musisz załadować go w ten sposób:

    // 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
źródło
1
To było dla mnie rozwiązanie i zdecydowanie najłatwiejsze.
Guillaume Bois