Rendering programmatico di un blocco in un modello di ramoscello


28

Devo eseguire il rendering di un blocco visualizzazioni nel mio modello page.html.twig. In D7 farei questo:

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

In Drupal 8 module_invoke è obsoleto e si consiglia di utilizzare questo: (Ho aggiunto il nome del blocco come secondo parametro)

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

Ho provato alcune cose. Per prima cosa ho provato a farlo in un modello di ramoscello ma non so come chiamare le funzioni php in un modello di ramoscello, quindi non è andata troppo bene.

Quindi ho chiamato la funzione nella funzione preprocess_page () nel file .theme ma prima che potessi farlo funzionare ho provato qualcosa di più semplice solo per provare a far funzionare una variabile all'interno del modello di ramoscello che non funzionava neanche, ad esempio:

Nella funzione template_preprocess_page (& $ vars) nel file .theme:

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

Ho provato a chiamare my_var all'interno del modello di ramoscello ma non ha funzionato e ho ricevuto un messaggio di errore che diceva "Il sito ha un errore, si prega di contattare l'amministratore"

Quindi, per riassumere, ecco le mie domande:

  1. Come posso rendere disponibili le variabili all'interno dei modelli di ramoscello?
  2. Come posso chiamare le funzioni all'interno dei modelli di ramoscello?
  3. Rendo i blocchi all'interno del file .theme o del modello di ramoscello?

Risposte:


47

Sei sulla strada sbagliata con module_invoke (). Questo è solo un modo elegante di chiamare la funzione {$ module_name} _block_view ().

Il fatto che sia cambiato non ha importanza, il punto è che il sistema a blocchi è completamente cambiato in 8.xe ora utilizza plugin ed entità di configurazione, queste funzioni non esistono più.

Hai alcune opzioni.

a) Riutilizzare un'entità di configurazione del blocco esistente e visualizzarla. Molto semplice, ma richiede che esista quella configurazione, ad es. Come blocco disabilitato.

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

b) Crea direttamente l'istanza del plug-in di blocco, passale la configurazione (puoi trovare facilmente l'ID del plug-in di blocco e la configurazione in un'entità di configurazione del blocco esportata). Il rovescio della medaglia è che non si ottiene la memorizzazione nella cache di rendering, ma se la si visualizza in un punto già memorizzato nella cache (come un modello di nodo), non importa.

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

c) Nel caso di una vista, è anche possibile caricare la vista direttamente e visualizzarla.

d) Puoi anche ripensare completamente il tuo approccio e utilizzare le regioni di blocco o Page Manager (che utilizza plug-in di blocco standard in 8.x).


La ringrazio per la risposta. Vorrei andare con A o B. Una regione funzionerà ma voglio evitare di usare una regione. L'unico problema che sto riscontrando è quando chiamo block_output nel modello di ramoscello ho un errore - "Nome tag imprevisto" block_output ", quindi non so come rendere disponibile quella variabile anche se l'ho creata nella funzione preprocess_page. Proverò a risolverlo.
Rick Bergmann,

Sembra che tu stia utilizzando {%? Usa {{block_output}}.
Berdir,

Sì, era quello! Sto ancora cercando di capire come funziona il ramoscello. Grazie.
Rick Bergmann,

Poiché Drupal 8.0.0 entityManager è obsoleto. Utilizzare invece entityTypeManager .
Philipp Michael,

dove metto questo codice? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ variabili ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Grazie!

11

In Drupal 8, questo funziona per il rendering di un plug-in a blocchi (ovvero uno che hai creato in un modulo personalizzato) in 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();
}

Puoi quindi renderlo nel tuo modello di ramoscello in questo modo:

{{ content.custom_block_output }}

Nota: questo caricherà una versione generica del tuo blocco. Se vuoi caricare un'istanza del tuo blocco con variabili (dopo averlo creato in / admin / struttura / blocco), devi caricarlo in questo modo:

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

1
Questa è stata la soluzione per me e di gran lunga la più semplice.
Guillaume Bois,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.