Programmgesteuertes Rendern eines Blocks in einer Zweigvorlage

28

Ich muss einen Ansichtenblock in meiner page.html.twig-Vorlage rendern. In D7 würde ich das machen:

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

In Drupal 8 ist module_invoke veraltet und es wird empfohlen, dies zu verwenden: (Ich habe den Namen des Blocks als zweiten Parameter hinzugefügt.)

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

Ich habe ein paar Dinge ausprobiert. Zuerst habe ich versucht, es in einem Zweig-Template zu tun, aber ich weiß nicht, wie man PHP-Funktionen in einem Zweig-Template aufruft, so dass es nicht allzu gut geworden ist.

Dann habe ich die Funktion in der preprocess_page () - Funktion in der .theme-Datei aufgerufen, aber bevor ich sie zum Laufen bringen konnte, habe ich etwas Einfacheres versucht, nur um zu versuchen, eine Variable innerhalb der Zweigvorlage arbeiten zu lassen, die auch nicht funktionierte, zum Beispiel:

In der Funktion template_preprocess_page (& $ vars) in der Datei .theme:

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

Ich habe versucht, my_var in der Zweigvorlage aufzurufen, aber es hat nicht funktioniert, und es wurde die Fehlermeldung "Die Website weist einen Fehler auf. Wenden Sie sich an den Administrator."

Zusammenfassend sind hier meine Fragen:

  1. Wie stelle ich Variablen in Zweigvorlagen zur Verfügung?
  2. Wie rufe ich Funktionen in Zweigvorlagen auf?
  3. Rendere ich Blöcke in der .theme-Datei oder in der Zweigvorlage?
Rick Bergmann
quelle

Antworten:

47

Sie sind mit module_invoke () auf dem falschen Weg. Das ist nur eine ausgefallene Art, die Funktion {$ module_name} _block_view () aufzurufen.

Die Tatsache, dass es sich geändert hat, spielt keine Rolle, der Punkt ist, dass sich das Blocksystem in 8.x komplett geändert hat und jetzt Plugins und Konfigurationsentitäten verwendet, diese Funktionen existieren nicht mehr.

Sie haben ein paar Möglichkeiten.

a) Verwenden Sie eine vorhandene Blockkonfigurationsentität erneut und zeigen Sie sie an. Sehr einfach, setzt jedoch voraus, dass die Konfiguration vorhanden ist, z. B. als deaktivierter Block.

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

b) Erstellen Sie die Block-Plugin-Instanz direkt und übergeben Sie ihr die Konfiguration (Sie können die Block-Plugin-ID und Konfiguration einfach in einer exportierten Block-Konfigurationsentität finden). Der Nachteil ist, dass Sie kein Render-Caching erhalten. Wenn Sie es jedoch an einer Stelle anzeigen, die bereits zwischengespeichert ist (z. B. bei einer Knotenvorlage), spielt dies keine Rolle.

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

c) Im Falle einer Ansicht können Sie die Ansicht auch direkt laden und anzeigen.

d) Sie können Ihren Ansatz auch komplett überdenken und Blockregionen oder den Seiten-Manager (der Standard-Block-Plugins in 8.x verwendet) verwenden.

Berdir
quelle
Vielen Dank für Ihre Antwort. Ich würde gerne mit A oder B gehen. Eine Region wird funktionieren, aber ich möchte vermeiden, eine Region zu verwenden. Das einzige Problem, das ich habe, ist, wenn ich block_output in der Zweigvorlage aufrufe. Ich habe einen Fehler - "Unerwarteter Tag-Name" block_output ". Daher weiß ich nicht, wie ich diese Variable verfügbar machen kann, obwohl ich sie in der Funktion preprocess_page erstellt habe. Ich werde versuchen, es herauszufinden.
Rick Bergmann
Klingt so, als würdest du {%? Verwenden Sie {{block_output}}.
Berdir
Ja das war es Ich versuche immer noch, den Dreh raus zu kriegen. Vielen Dank.
Rick Bergmann
Seit Drupal 8.0.0 ist entityManager veraltet. Verwenden Sie stattdessen entityTypeManager .
Philipp Michael
Wo lege ich diesen Code ab? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ variables ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Vielen Dank!
11

In Drupal 8 funktioniert dies zum Rendern eines Block-Plugins (das heißt eines, das Sie in einem benutzerdefinierten Modul erstellt haben) in einem 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();
}

Sie können es dann wie folgt in Ihrer Zweigvorlage rendern:

{{ content.custom_block_output }}

Hinweis: Dadurch wird eine allgemeine Version Ihres Blocks geladen. Wenn Sie eine Instanz Ihres Blocks mit Variablen laden möchten (nachdem Sie sie unter / admin / structure / block erstellt haben), müssen Sie sie folgendermaßen laden:

    // 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
quelle
1
Dies war die Lösung für mich und bei weitem die einfachste.
Guillaume Bois